diff --git a/.gitignore b/.gitignore index bceaf41a73abf285da9abdc484f2e55401c648dd..32b5db376ac09f7ec5e07924dbf0401d064b6cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ IVAS_cod IVAS_dec IVAS_rend +ISAR_post_rend obj/ *.a *.o @@ -16,6 +17,7 @@ build*/**/* IVAS_cod.exe IVAS_dec.exe IVAS_rend.exe +ISAR_post_rend.exe *.user .vs/ Debug_*/ @@ -54,10 +56,12 @@ scripts/testv/stvOMASA_*.met scripts/testv/stvOMASA_*.csv scripts/testv/stvOMASA_2ISM_1MASA1TC48c.wav scripts/testv/stvOMASA_3ISM_1MASA1TC48c.wav +scripts/testv/stvO* # default reference binary name IVAS_cod_ref* IVAS_dec_ref* IVAS_rend_ref* +ISAR_post_rend_ref* # Python files that pop up when running scripts __pycache__/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 153b0ca11abb42805c86b17052bd916500fe3bc5..399cb6f22e5bf2de53ec28b4f8f670dff7cf4259 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,14 +4,15 @@ variables: BUILD_OUTPUT: "build_output.txt" EVS_BE_TEST_DIR: "/usr/local/be_2_evs_test" EVS_BE_WIN_TEST_DIR: "C:/Users/gitlab-runner/testvec" - SANITIZER_TESTS: "CLANG1 CLANG2 CLANG3" - 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_IR BINAURAL_ROOM_REVERB" EXIT_CODE_NON_BE: 123 EXIT_CODE_FAIL: 1 PROCESSING_SCRIPTS_BIN_DIR: "/test-bin" TESTS_DIR_CODEC_BE_ON_MR: "tests/codec_be_on_mr_nonselection" + SANITIZER_TESTS: "CLANG1 CLANG2 CLANG3" + 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_IR BINAURAL_ROOM_REVERB" + OUT_FORMATS_ALL: "$OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT" IVAS_PIPELINE_NAME: '' MANUAL_PIPELINE_TYPE: description: "Type for the manual pipeline run. Use 'test-be-release' to run BE test against release codec." @@ -167,10 +168,11 @@ stages: - git pull - cd - -.enable-split-rendering: &enable-split-rendering -# automatically enable #define SPLIT_REND_WITH_HEAD_ROT in options.h, handling both /**/-comment and //-comment - - sed -i.bak -e "s/\/\*[[:space:]]*\(#define[[:space:]]*SPLIT_REND_WITH_HEAD_ROT\)[[:space:]]*\*\//\1/g" ./lib_com/options.h - - sed -i.bak -e "s/\/\/[[:space:]]*\(#define[[:space:]]*SPLIT_REND_WITH_HEAD_ROT\)/\1/g" ./lib_com/options.h +.update-ltv-repo-win: &update-ltv-repo-win + - Push-Location + - cd $LTV_DIR_WIN + - git pull + - Pop-Location .disable-limiter: &disable-limiter # automatically enable #define DISABLE_LIMITER in options.h, handling both /**/-comment and //-comment @@ -189,6 +191,11 @@ stages: - cp "$LTV_DIR"/*.met scripts/testv/ - cp "$LTV_DIR"/*.csv scripts/testv/ +.copy-ltv-files-to-testv-dir-win: ©-ltv-files-to-testv-dir-win + - cp $LTV_DIR_WIN\*.wav scripts\testv + - cp $LTV_DIR_WIN\*.met scripts\testv + - cp $LTV_DIR_WIN\*.csv scripts\testv + .activate-Werror-linux: &activate-Werror-linux - sed -i.bak "s/^# \(CFLAGS += -Werror\)/\1/" Makefile - sed -i.bak "s/# \(set(CMAKE_C_FLAGS \"\${CMAKE_C_FLAGS} -Werror\")\)/\1/" CMakeLists.txt @@ -215,12 +222,12 @@ stages: - if [ $CLANG_NUM -eq 1 ]; then sanitizer_type="MemorySanitizer"; elif [ $CLANG_NUM -eq 2 ]; then sanitizer_type="AddressSanitizer"; elif [ $CLANG_NUM -eq 3 ]; then sanitizer_type="UndefinedBehaviorSanitizer"; else echo "Wrong CLANG_NUM $CLANG_NUM given!"; exit 1; fi # run encoder and decoder with 20ms renderer framesize first, use reference creation mode - - python3 -m pytest $SELF_TEST_PRM_FILE -v --update_ref 1 -m create_ref --html=report-20ms.html --self-contained-html --junit-xml=report-junit-20ms.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code20=$? + - python3 -m pytest tests/codec_be_on_mr_nonselection/test_param_file.py --param_file $SELF_TEST_PRM_FILE -v --update_ref 1 -m create_ref --html=report-20ms.html --self-contained-html --junit-xml=report-junit-20ms.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code20=$? # for 10ms and 5ms renderer framesize, we only need to run the decoder part as renderer framesize is a decoder-only option # set tolerance very high do ignore any BE differences due to the different renderer framesizes, those can appear due to the limiter being active # we are only interested in runtime errors from the sanitizers and ignore the diffs - - python3 -m pytest $SELF_TEST_PRM_FILE -v --html=report-5ms.html --self-contained-html --junit-xml=report-junit-5ms.xml --dut_fr 5 --decoder_only --abs_tol 100000 || exit_code5=$? - - python3 -m pytest $SELF_TEST_PRM_FILE -v --html=report-10ms.html --self-contained-html --junit-xml=report-junit-10ms.xml --dut_fr 10 --decoder_only --abs_tol 100000 || exit_code10=$? + - python3 -m pytest tests/codec_be_on_mr_nonselection/test_param_file.py --param_file $SELF_TEST_PRM_FILE -v --html=report-5ms.html --self-contained-html --junit-xml=report-junit-5ms.xml --dut_fr 5 --decoder_only --abs_tol 100000 || exit_code5=$? + - python3 -m pytest tests/codec_be_on_mr_nonselection/test_param_file.py --param_file $SELF_TEST_PRM_FILE -v --html=report-10ms.html --self-contained-html --junit-xml=report-junit-10ms.xml --dut_fr 10 --decoder_only --abs_tol 100000 || exit_code10=$? - if [ $exit_code20 -ne 0 ] || [ $exit_code10 -ne 0 ] || [ $exit_code5 -ne 0 ]; then exit 1; fi @@ -379,6 +386,17 @@ branch-is-up-to-date-with-main-pre: - echo $commits_behind_count - if [ $commits_behind_count -eq 0 ]; then exit 0; else echo "Your branch is behind main, run 'git merge origin/main' to update."; exit 1; fi; +check-self-test-names-pre: + extends: + - .rules-merge-request + stage: prevalidate + needs: [] + tags: + - ivas-linux + script: + - python3 ci/check_self_test_names.py scripts/config/self_test.prm 135 + + branch-is-up-to-date-with-main-post: extends: - .rules-merge-request @@ -420,7 +438,7 @@ build-codec-instrumented-linux: extends: - .build-job-linux - .rules-basis - timeout: "7 minutes" + timeout: "10 minutes" script: - *print-common-info - *activate-Werror-linux @@ -437,30 +455,6 @@ build-codec-sanitizers-linux: - *activate-Werror-linux - bash ci/build_codec_sanitizers_linux.sh -build-codec-include-split-linux-make: - extends: - - .build-job-linux - - .rules-basis - script: - - *print-common-info - - *enable-split-rendering - - *activate-Werror-linux - - make -j INCLUDE_SPLIT=1 - -build-codec-include-split-linux-cmake: - extends: - - .build-job-linux - - .rules-basis - script: - - *print-common-info - - *enable-split-rendering - - *activate-Werror-linux - - mkdir build - - cd build - - cmake .. -DINCLUDE_SPLIT=1 - - cd .. - - make -C build -j - build-codec-windows-cmake: extends: - .build-job-windows @@ -471,19 +465,6 @@ build-codec-windows-cmake: - cmake -G "Visual Studio 15 2017" . -Bbuild - cmake --build build -j -build-codec-windows-include-split-cmake: - extends: - - .build-job-windows - - .rules-basis - script: - - *print-common-info-windows - - *activate-WX-windows - - get-content .\lib_com\options.h | %{$_ -replace "/\*#define[\s]*SPLIT_REND_WITH_HEAD_ROT[\s]*\*/", "#define SPLIT_REND_WITH_HEAD_ROT"} | set-content -Path ./options_patched.h - - rm ./lib_com/options.h - - mv ./options_patched.h ./lib_com/options.h - - cmake -DINCLUDE_SPLIT=1 -G "Visual Studio 15 2017" . -Bbuild - - cmake --build build -j - build-codec-windows-msbuild: extends: - .build-job-windows @@ -491,7 +472,6 @@ build-codec-windows-msbuild: script: - *print-common-info-windows - *activate-WX-windows - - python .\scripts\strip_split_rendering.py - MSBuild.exe -maxcpucount .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug # --------------------------------------------------------------- @@ -514,11 +494,10 @@ codec-smoke-test: - *update-ltv-repo - bash ci/smoke_test.sh ### analyze for failures - - if ! [ -s smoke_test_output.txt ] || ! [ -s smoke_test_output_plc.txt ] || ! [ -s smoke_test_output_jbm_noEXT.txt ] || ! [ -s smoke_test_output_hrtf.txt ]; then echo "Error in smoke test"; exit 1; fi + - if ! [ -s smoke_test_output.txt ] || ! [ -s smoke_test_output_jbm.txt ] || ! [ -s smoke_test_output_hrtf.txt ]; then echo "Error in smoke test"; exit 1; fi - ret_val=0 - - if cat smoke_test_output.txt | grep -c "failed"; then echo "Smoke test without PLC failed"; ret_val=1; fi - - if cat smoke_test_output_plc.txt | grep -c "failed"; then echo "Smoke test with PLC failed"; ret_val=1; fi - - if cat smoke_test_output_jbm_noEXT.txt | grep -c "failed"; then echo "Smoke test JBM part failed"; ret_val=1; fi + - if cat smoke_test_output.txt | grep -c "failed"; then echo "Smoke test without JBM failed"; ret_val=1; fi + - if cat smoke_test_output_jbm.txt | grep -c "failed"; then echo "Smoke test JBM part failed"; ret_val=1; fi - if cat smoke_test_output_hrtf.txt | grep -c "failed"; then echo "Smoke test with external hrtf files failed"; ret_val=1; fi - exit $ret_val artifacts: @@ -527,8 +506,7 @@ codec-smoke-test: when: always paths: - smoke_test_output.txt - - smoke_test_output_plc.txt - - smoke_test_output_jbm_noEXT.txt + - smoke_test_output_jbm.txt - smoke_test_output_hrtf.txt expose_as: "Smoke test results" @@ -541,7 +519,7 @@ codec-msan: before_script: - CLANG_NUM=1 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS - - SELF_TEST_PRM_FILE="tests/codec_be_on_mr_nonselection/test_param_file.py" + - SELF_TEST_PRM_FILE="scripts/config/self_test.prm" <<: *sanitizer-selftest-anchor # code selftest testvectors with address-sanitizer binaries @@ -551,7 +529,7 @@ codec-asan: before_script: - CLANG_NUM=2 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS - - SELF_TEST_PRM_FILE="tests/codec_be_on_mr_nonselection/test_param_file.py" + - SELF_TEST_PRM_FILE="scripts/config/self_test.prm" <<: *sanitizer-selftest-anchor # code selftest testvectors with undefined-behaviour-sanitizer binaries @@ -563,7 +541,7 @@ codec-usan: before_script: - CLANG_NUM=3 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS - - SELF_TEST_PRM_FILE="tests/codec_be_on_mr_nonselection/test_param_file.py" + - SELF_TEST_PRM_FILE="scripts/config/self_test.prm" <<: *sanitizer-selftest-anchor # compare bit-exactness between 5ms and 20 on the branch @@ -581,8 +559,6 @@ pytest-compare-20ms-and-5ms-rendering: ### prepare pytest - cp IVAS_cod IVAS_cod_ref - cp IVAS_dec IVAS_dec_ref - # create short test vectors - - python3 tests/create_short_testvectors.py # create references - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 -m create_ref - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 -m create_ref_part2 @@ -774,8 +750,7 @@ split-rendering-smoke-test: needs: ["build-codec-linux-make"] stage: test script: - - *enable-split-rendering - - make -j INCLUDE_SPLIT=1 + - make -j - testcase_timeout=10 - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --testcase_timeout=$testcase_timeout artifacts: @@ -789,6 +764,17 @@ split-rendering-smoke-test: junit: - report-junit.xml +lc3-wrapper-unit-test: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true + - cmake --build cmake-build -- -j + - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test + # compare split-rendering bitexactness between target and source branch split-rendering-pytest-on-merge-request: extends: @@ -818,8 +804,7 @@ split-rendering-pytest-on-merge-request: - echo "Building reference codec at commit $target_commit" # build reference binaries - - *enable-split-rendering - - make -j INCLUDE_SPLIT=1 + - make -j - mv IVAS_cod IVAS_cod_ref - mv IVAS_dec IVAS_dec_ref - mv IVAS_rend IVAS_rend_ref @@ -835,8 +820,7 @@ split-rendering-pytest-on-merge-request: - git restore lib_com/options.h # Revert changes back before checking out another branch to avoid conflicts - git checkout $source_branch_commit_sha - make clean - - *enable-split-rendering - - make -j INCLUDE_SPLIT=1 + - make -j ### Run test using scripts and input from main - if [ $ref_using_main == 1 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts @@ -887,8 +871,6 @@ ivas-pytest-on-merge-request: - if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi ### prepare pytest - # create short test vectors - - python3 tests/create_short_testvectors.py # create references - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 -m create_ref - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 -m create_ref_part2 @@ -942,8 +924,6 @@ ivas-interop-on-merge-request: - non_interop_flag=$(grep -c --ignore-case "\[non[ -]*io\]" tmp.txt) || true ### prepare pytest - # create short test vectors - - python3 tests/create_short_testvectors.py # Run reference creation, using source branch encoder and main decoder (see .merge-request-comparison-setup-codec) - exit_code=0 @@ -1150,7 +1130,7 @@ check-bitexactness-hrtf-rom-and-file: - *print-common-info - cmake . - make -j - - python3 tests/create_short_testvectors.py --which all --cut_len 1.0 + - python3 tests/create_short_testvectors.py --cut_len 1.0 - python3 -m pytest tests/hrtf_binary_loading --html=report.html --junit-xml=report-junit.xml --self-contained-html artifacts: paths: @@ -1161,6 +1141,28 @@ check-bitexactness-hrtf-rom-and-file: expose_as: "logs-hrtf-loading" expire_in: "5 days" +check-bitexactness-ext-and-transport-format: + extends: + - .test-job-linux + - .rules-merge-request + stage: test + needs: ["build-codec-linux-cmake"] + timeout: "5 minutes" + script: + - *print-common-info + - cmake . + - make -j + - python3 tests/create_short_testvectors.py --cut_len 1.0 + - python3 -m pytest tests/test_be_for_ext_outputs.py --html=report.html --junit-xml=report-junit.xml --self-contained-html + artifacts: + paths: + - report.html + - report-junit.xml + when: always + name: "$CI_JOB_NAME--$CI_MERGE_REQUEST_ID--sha-$CI_COMMIT_SHA--ext-sanity-check" + expose_as: "logs-ext-sanity-check" + expire_in: "5 days" + # --------------------------------------------------------------- # Test jobs for main branch @@ -1267,8 +1269,6 @@ codec-comparison-on-main-push: - if [ $ref_using_main == 0 ]; then git checkout $latest_commit;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 @@ -1337,45 +1337,45 @@ ivas-conformance: tags: - ivas-windows stage: test - timeout: "60 minutes" + timeout: "90 minutes" rules: - if: ($CI_PIPELINE_SOURCE == 'web' || $CI_PIPELINE_SOURCE == 'trigger') && $MANUAL_PIPELINE_TYPE == 'ivas-conformance' + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH allow_failure: exit_codes: - 123 script: - - *print-common-info-windows - # Prepare reference exec, use tests and scripts from reference - - $source_branch_commit_sha = $(git rev-parse HEAD) - - git checkout main # This should be set to a relevant reference - - git pull # Ensure to get the latest version - - python .\scripts\strip_split_rendering.py + - *print-common-info-windows - MSBuild.exe -maxcpucount .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug - cp -force IVAS_cod.exe IVAS_cod_ref.exe - cp -force IVAS_dec.exe IVAS_dec_ref.exe - - cp -force IVAS_rend.exe IVAS_rend_ref.exe - - git restore . - - git checkout $source_branch_commit_sha + - cp -force IVAS_rend.exe IVAS_rend_ref.exe # Reference creation - - python tests/create_short_testvectors.py - python scripts/prepare_combined_format_inputs.py - - python -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref --keep_files - - python -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref_part2 --keep_files - - python -m pytest tests/renderer/test_renderer.py --create_ref --keep_files + - $TEST_SET = "tests/codec_be_on_mr_nonselection", "tests/renderer/test_renderer.py", "tests/split_rendering/test_split_rendering.py" + - python -m pytest $TEST_SET -v -n auto --update_ref 1 -m create_ref --create_ref --keep_files + - python -m pytest $TEST_SET -v -n auto --update_ref 1 -m create_ref_part2 --keep_files # Output creation - - python -m pytest tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html + - python -m pytest $TEST_SET -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html - python scripts/parse_commands.py report_cmd.html Readme_IVAS.txt # Copy input data and output ref data - if (Test-Path testvec) {rm -r -force testvec} + - if (Test-Path TMP_DEC) {rm -r -force TMP_DEC} + - if (Test-Path TMP_ENC) {rm -r -force TMP_ENC} + - if (Test-Path TMP_JBM) {rm -r -force TMP_JBM} + - if (Test-Path TMP_REND) {rm -r -force TMP_REND} + - if (Test-Path TMP_ISAR_POST_REND) {rm -r -force TMP_ISAR_POST_REND} + - if (Test-Path TMP_DEC_ISAR) {rm -r -force TMP_DEC_ISAR} - mkdir testvec - mkdir testvec/binauralRenderer_interface - mkdir testvec/testv - mkdir testvec/testv/renderer + - mkdir testvec/testv/split_rendering - mkdir testvec/bin - - cp -r -force -ErrorAction Ignore scripts/testv/* testvec/testv + - cp -force -ErrorAction Ignore scripts/testv/* testvec/testv - cp -r -force -ErrorAction Ignore scripts/ls_layouts testvec - cp -r -force -ErrorAction Ignore scripts/switchPaths testvec - cp -r -force -ErrorAction Ignore scripts/trajectories testvec @@ -1383,14 +1383,26 @@ ivas-conformance: - cp -r -force -ErrorAction Ignore tests/ref testvec/testv/ref - cp -r -force -ErrorAction Ignore tests/dut/* testvec/testv/ref - cp -r -force -ErrorAction Ignore tests/renderer/cut testvec/testv/renderer/ref + - cp -r -force -ErrorAction Ignore tests/split_rendering/cut testvec/testv/split_rendering/ref + - cp -r -force -ErrorAction Ignore tests/split_rendering/renderer_configs testvec/testv/split_rendering/renderer_configs + - cp -r -force -ErrorAction Ignore tests/split_rendering/error_patterns testvec/testv/split_rendering/error_patterns + + # Remove redundant files + - python scripts/cleanup_26252.py + + # Copy test script files - cp -r -force -ErrorAction Ignore tests/conformance-test testvec/ - cp Readme_IVAS_dec.txt testvec - cp Readme_IVAS_enc.txt testvec - cp Readme_IVAS_rend.txt testvec - cp Readme_IVAS_JBM_dec.txt testvec + - cp Readme_IVAS_ISAR_dec.txt testvec + - cp Readme_IVAS_ISAR_post_rend.txt testvec - cp IVAS_cod.exe testvec/bin - cp IVAS_dec.exe testvec/bin - cp IVAS_rend.exe testvec/bin + - cp ISAR_post_rend.exe testvec/bin + # Test run generated scripts in testvec - cd testvec @@ -1409,6 +1421,8 @@ ivas-conformance: - Readme_IVAS_enc.txt - Readme_IVAS_rend.txt - Readme_IVAS_JBM_dec.txt + - Readme_IVAS_ISAR_dec.txt + - Readme_IVAS_ISAR_post_rend.txt expose_as: "Draft IVAS conformance" reports: junit: report-junit.xml @@ -1417,7 +1431,7 @@ ivas-conformance-linux: tags: - ivas-linux stage: test - timeout: "60 minutes" + timeout: "90 minutes" rules: - if: ($CI_PIPELINE_SOURCE == 'web' || $CI_PIPELINE_SOURCE == 'trigger') && $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' allow_failure: @@ -1425,26 +1439,19 @@ ivas-conformance-linux: - 123 script: - *print-common-info - # Prepare reference exec, use tests and scripts from reference - - source_branch_commit_sha=$(git rev-parse HEAD) - - git checkout main # This should be set to a relevant reference - - make -j - cp IVAS_cod IVAS_cod_ref - cp IVAS_dec IVAS_dec_ref - cp IVAS_rend IVAS_rend_ref - - git restore . - - git checkout $source_branch_commit_sha # Reference creation - - python3 tests/create_short_testvectors.py - python3 scripts/prepare_combined_format_inputs.py - - python3 -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref --keep_files - - python3 -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref_part2 --keep_files - - python3 -m pytest tests/renderer/test_renderer.py --create_ref --keep_files + - TEST_SET="tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py tests/split_rendering/test_split_rendering.py" + - python3 -m pytest $TEST_SET -v -n auto --update_ref 1 -m create_ref --create_ref --keep_files + - python3 -m pytest $TEST_SET -v -n auto --update_ref 1 -m create_ref_part2 --keep_files # Output creation - - python3 -m pytest tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html + - python3 -m pytest $TEST_SET -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html - python3 scripts/parse_commands.py report_cmd.html Readme_IVAS.txt # Copy input data and output ref data @@ -1453,6 +1460,7 @@ ivas-conformance-linux: - mkdir testvec/binauralRenderer_interface - mkdir testvec/testv - mkdir testvec/testv/renderer + - mkdir testvec/testv/split_rendering - mkdir testvec/bin - cp -r scripts/testv/* testvec/testv - cp -r scripts/ls_layouts testvec @@ -1462,32 +1470,65 @@ ivas-conformance-linux: - cp -r tests/ref testvec/testv/ref - cp -r tests/dut/* testvec/testv/ref - cp -r tests/renderer/cut testvec/testv/renderer/ref + - cp -r tests/split_rendering/cut testvec/testv/split_rendering/ref + - cp -r tests/split_rendering/renderer_configs testvec/testv/split_rendering/renderer_configs + - cp -r tests/split_rendering/error_patterns testvec/testv/split_rendering/error_patterns + + # Remove redundant files + - python3 scripts/cleanup_26252.py + + # Copy test script files - cp -r tests/conformance-test testvec/ - cp Readme_IVAS_dec.txt testvec - cp Readme_IVAS_enc.txt testvec - cp Readme_IVAS_rend.txt testvec - cp Readme_IVAS_JBM_dec.txt testvec + - cp Readme_IVAS_ISAR_dec.txt testvec + - cp Readme_IVAS_ISAR_post_rend.txt testvec + + # Create GCOV execs for coverage analysis + - make clean + - make GCOV=1 -j + - cp IVAS_cod testvec/bin - cp IVAS_dec testvec/bin - cp IVAS_rend testvec/bin - + - cp ISAR_post_rend testvec/bin + # Test run generated scripts in testvec - - cd testvec - - python3 -m pytest conformance-test/test_26252.py --junit-xml=report-junit.xml --html=report.html --self-contained-html + - cd testvec + - exit_code=0 + - python3 -m pytest conformance-test/test_26252.py --junit-xml=report-junit.xml --html=report.html --self-contained-html || exit_code=$? - mv report.html .. - mv report-junit.xml .. + # Collect coverage + - cd - + - lcov -c -d obj -o coverage.info + - lcov -r coverage.info "*apps*" -o coverage.info + - lcov -r coverage.info "*lib_util*" -o coverage.info + - commit_sha=$(git rev-parse HEAD) + - genhtml coverage.info -o coverage -t "Coverage on main @ $commit_sha" + + # Check for failures + - if [ $exit_code -eq 1 ]; then echo "Test failures encountered"; exit $EXIT_CODE_FAIL; fi + artifacts: name: "ivas-conformance-linux-$CI_COMMIT_SHORT_SHA" expire_in: 1 week when: always paths: + - report_cmd.html - report-junit.xml - report.html - Readme_IVAS_dec.txt - Readme_IVAS_enc.txt - Readme_IVAS_rend.txt - Readme_IVAS_JBM_dec.txt + - Readme_IVAS_ISAR_dec.txt + - Readme_IVAS_ISAR_post_rend.txt + - coverage.info + - coverage expose_as: "Draft IVAS conformance -- Linux" reports: junit: report-junit.xml @@ -1574,13 +1615,13 @@ ltv-msan: - .sanitizer-selftest-ltv rules: - if: $SANITIZER_SCHEDULE_E - timeout: 2 hour + timeout: 4 hour tags: - ivas-linux-fast before_script: - CLANG_NUM=1 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS - - SELF_TEST_PRM_FILE="tests/test_param_file_ltv.py" + - SELF_TEST_PRM_FILE="scripts/config/self_test_ltv.prm" <<: *sanitizer-selftest-anchor # code selftest long testvectors with address-sanitizer binaries @@ -1590,14 +1631,14 @@ ltv-asan: rules: - if: $SANITIZER_SCHEDULE_E when: delayed - start_in: 2 hours + start_in: 4 hours tags: - ivas-linux-fast - timeout: 2 hour + timeout: 3 hour before_script: - CLANG_NUM=2 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS - - SELF_TEST_PRM_FILE="tests/test_param_file_ltv.py" + - SELF_TEST_PRM_FILE="scripts/config/self_test_ltv.prm" <<: *sanitizer-selftest-anchor # code selftest long testvectors with undefined-behaviour-sanitizer binaries @@ -1607,14 +1648,14 @@ ltv-usan: rules: - if: $SANITIZER_SCHEDULE_E when: delayed - start_in: 3 hours + start_in: 7 hours tags: - ivas-linux-fast - timeout: 2 hour + timeout: 3 hour before_script: - CLANG_NUM=3 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS - - SELF_TEST_PRM_FILE="tests/test_param_file_ltv.py" + - SELF_TEST_PRM_FILE="scripts/config/self_test_ltv.prm" <<: *sanitizer-selftest-anchor .sanitizer-test-template: @@ -1660,7 +1701,7 @@ sanitizer-test-stereo: timeout: 2.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED EXT --tests $SANITIZER_TESTS sanitizer-test-stereodmxevs: extends: .sanitizer-test-schedule-A @@ -1682,7 +1723,7 @@ sanitizer-test-mc-5_1: timeout: 2.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py 5_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py 5_1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-mc-5_1_2: extends: .sanitizer-test-schedule-A @@ -1693,7 +1734,7 @@ sanitizer-test-mc-5_1_2: timeout: 2.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py 5_1_2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py 5_1_2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-mc-5_1_4: extends: .sanitizer-test-schedule-A @@ -1704,7 +1745,7 @@ sanitizer-test-mc-5_1_4: timeout: 3.75 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py 5_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py 5_1_4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-mc-7_1: extends: .sanitizer-test-schedule-A @@ -1715,7 +1756,7 @@ sanitizer-test-mc-7_1: timeout: 2.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py 7_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py 7_1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-mc-7_1_4: extends: .sanitizer-test-schedule-A @@ -1726,7 +1767,7 @@ sanitizer-test-mc-7_1_4: timeout: 5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py 7_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py 7_1_4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-ism+1: extends: .sanitizer-test-schedule-A @@ -1737,7 +1778,7 @@ sanitizer-test-ism+1: timeout: 1.25 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-ism+2: extends: .sanitizer-test-schedule-A @@ -1748,7 +1789,7 @@ sanitizer-test-ism+2: timeout: 2.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-ism+3: extends: .sanitizer-test-schedule-A @@ -1759,7 +1800,7 @@ sanitizer-test-ism+3: timeout: 3.75 hour script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-ism+4: extends: .sanitizer-test-schedule-A @@ -1770,7 +1811,7 @@ sanitizer-test-ism+4: timeout: 5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-masa: extends: .sanitizer-test-schedule-A @@ -1781,7 +1822,7 @@ sanitizer-test-masa: timeout: 10 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_ALL --tests $SANITIZER_TESTS ### --- sanitizer schedule B --- @@ -1796,7 +1837,7 @@ sanitizer-test-foa: - if: $SANITIZER_SCHEDULE_B script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py FOA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py FOA $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-hoa2: extends: .sanitizer-test-schedule-B @@ -1806,7 +1847,7 @@ sanitizer-test-hoa2: start_in: 7.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-hoa3: extends: .sanitizer-test-schedule-B @@ -1816,7 +1857,7 @@ sanitizer-test-hoa3: start_in: 15 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-foa-ism1: extends: .sanitizer-test-schedule-B @@ -1826,7 +1867,7 @@ sanitizer-test-osba-foa-ism1: start_in: 22.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-foa-ism2: extends: .sanitizer-test-schedule-B @@ -1836,7 +1877,7 @@ sanitizer-test-osba-foa-ism2: start_in: 30 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-foa-ism3: extends: .sanitizer-test-schedule-B @@ -1846,7 +1887,7 @@ sanitizer-test-osba-foa-ism3: start_in: 37.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-foa-ism4: extends: .sanitizer-test-schedule-B @@ -1856,7 +1897,7 @@ sanitizer-test-osba-foa-ism4: start_in: 45 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py FOA-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa2-ism1: extends: .sanitizer-test-schedule-B @@ -1866,7 +1907,7 @@ sanitizer-test-osba-hoa2-ism1: start_in: 52.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa2-ism2: extends: .sanitizer-test-schedule-B @@ -1876,7 +1917,7 @@ sanitizer-test-osba-hoa2-ism2: start_in: 60 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa2-ism3: extends: .sanitizer-test-schedule-B @@ -1886,7 +1927,7 @@ sanitizer-test-osba-hoa2-ism3: start_in: 67.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa2-ism4: extends: .sanitizer-test-schedule-B @@ -1896,7 +1937,7 @@ sanitizer-test-osba-hoa2-ism4: start_in: 75 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA2-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa3-ism1: extends: .sanitizer-test-schedule-B @@ -1906,7 +1947,7 @@ sanitizer-test-osba-hoa3-ism1: start_in: 82.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa3-ism2: extends: .sanitizer-test-schedule-B @@ -1916,7 +1957,7 @@ sanitizer-test-osba-hoa3-ism2: start_in: 90 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-omasa-ism4: extends: .sanitizer-test-schedule-B @@ -1927,7 +1968,7 @@ sanitizer-test-omasa-ism4: timeout: 10 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS ### --- sanitizer schedule C --- @@ -1943,7 +1984,7 @@ sanitizer-test-omasa-ism1: - if: $SANITIZER_SCHEDULE_C script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-omasa-ism2: extends: .sanitizer-test-schedule-C @@ -1953,7 +1994,7 @@ sanitizer-test-omasa-ism2: start_in: 10 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-omasa-ism3: extends: .sanitizer-test-schedule-C @@ -1963,7 +2004,7 @@ sanitizer-test-omasa-ism3: start_in: 20 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py MASA-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa3-ism3: extends: .sanitizer-test-schedule-C @@ -1974,7 +2015,7 @@ sanitizer-test-osba-hoa3-ism3: timeout: 7.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-hoa3-ism4: extends: .sanitizer-test-schedule-C @@ -1985,7 +2026,7 @@ sanitizer-test-osba-hoa3-ism4: timeout: 7.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py HOA3-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS ### --- sanitizer schedule D --- @@ -2000,7 +2041,7 @@ sanitizer-test-planar-foa: - if: $SANITIZER_SCHEDULE_D script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-planar-hoa2: extends: .sanitizer-test-schedule-D @@ -2010,7 +2051,7 @@ sanitizer-test-planar-hoa2: start_in: 7.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-planar-hoa3: extends: .sanitizer-test-schedule-D @@ -2020,7 +2061,7 @@ sanitizer-test-planar-hoa3: start_in: 15 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-foa-ism1: extends: .sanitizer-test-schedule-D @@ -2030,7 +2071,7 @@ sanitizer-test-osba-planar-foa-ism1: start_in: 22.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-foa-ism2: extends: .sanitizer-test-schedule-D @@ -2040,7 +2081,7 @@ sanitizer-test-osba-planar-foa-ism2: start_in: 30 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-foa-ism3: extends: .sanitizer-test-schedule-D @@ -2050,7 +2091,7 @@ sanitizer-test-osba-planar-foa-ism3: start_in: 37.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-foa-ism4: extends: .sanitizer-test-schedule-D @@ -2060,7 +2101,7 @@ sanitizer-test-osba-planar-foa-ism4: start_in: 45 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarFOA-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa2-ism1: extends: .sanitizer-test-schedule-D @@ -2070,7 +2111,7 @@ sanitizer-test-osba-planar-hoa2-ism1: start_in: 52.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa2-ism2: extends: .sanitizer-test-schedule-D @@ -2080,7 +2121,7 @@ sanitizer-test-osba-planar-hoa2-ism2: start_in: 60 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa2-ism3: extends: .sanitizer-test-schedule-D @@ -2090,7 +2131,7 @@ sanitizer-test-osba-planar-hoa2-ism3: start_in: 67.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa2-ism4: extends: .sanitizer-test-schedule-D @@ -2100,7 +2141,7 @@ sanitizer-test-osba-planar-hoa2-ism4: start_in: 75 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA2-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa3-ism1: extends: .sanitizer-test-schedule-D @@ -2110,7 +2151,7 @@ sanitizer-test-osba-planar-hoa3-ism1: start_in: 82.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM1 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa3-ism2: extends: .sanitizer-test-schedule-D @@ -2120,7 +2161,7 @@ sanitizer-test-osba-planar-hoa3-ism2: start_in: 90 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM2 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa3-ism3: extends: .sanitizer-test-schedule-D @@ -2130,7 +2171,7 @@ sanitizer-test-osba-planar-hoa3-ism3: start_in: 97.5 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM3 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS sanitizer-test-osba-planar-hoa3-ism4: extends: .sanitizer-test-schedule-D @@ -2140,7 +2181,8 @@ sanitizer-test-osba-planar-hoa3-ism4: start_in: 105 hours script: - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + - python3 ci/run_scheduled_sanitizer_test.py PlanarHOA3-ISM4 $OUT_FORMATS_ALL --tests $SANITIZER_TESTS + # GCOV/LCOV coverage analysis of self_test suite @@ -2161,7 +2203,6 @@ coverage-test-on-main-scheduled: - *copy-ltv-files-to-testv-dir - make GCOV=1 -j - cp IVAS_rend IVAS_rend_ref # Copy exec to be able to run renderer script - - python3 tests/create_short_testvectors.py - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v -n auto --update_ref 1 -m create_ref --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v -n auto --update_ref 1 -m create_ref_part2 --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec # need to ignore non-zero exit codes as limiter is active and thus the different framesiszes will not be BE in all cases @@ -2202,7 +2243,7 @@ coverage-test-on-main-scheduled: &complexity-measurements-setup # create necessary environment - mkdir -p wmops/logs - - job_id=$(python3 ci/get_id_of_last_job_occurence.py $CI_COMMIT_REF_NAME $CI_JOB_NAME) + - job_id=$(python3 ci/get_id_of_last_job_occurence.py $CI_COMMIT_REF_NAME $CI_JOB_NAME $CI_PROJECT_ID --success_only) - echo $job_id - curl --request GET "https://forge.3gpp.org/rep/api/v4/projects/$CI_PROJECT_ID/jobs/$job_id/artifacts" --output artifacts.zip - unzip artifacts.zip || true # this may fail on first run, when there are no artifacts there and the zip file is actually just "404"-html diff --git a/CMakeLists.txt b/CMakeLists.txt index 0267f6cc4b68482b9f496e710cbfce61bafb1f49..b400a280279b37eaa43bc23fe0fe225b7e1f4ae5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,14 +27,12 @@ # # or build on command line, e.g.: # cmake --build . --config Debug # cmake --build . --config Release -# -# INCLUDE_SPLIT is not set by default. If split rendering is used, then add -D INCLUDE_SPLIT=1 to the build command + cmake_minimum_required(VERSION 3.1) set(CMAKE_C_STANDARD 99) - # configuration options for UNIX if(UNIX) set(TARGET_PLATFORM "" CACHE STRING "i686 / x86_64") @@ -115,11 +113,6 @@ elseif(WIN32) -D_CRT_SECURE_NO_WARNINGS /MP ) - if(NOT INCLUDE_SPLIT) - add_compile_options("/W4") - # to be uncommented in CI - # add_compile_options("/WX") - endif() endif() # configuration options for all platforms @@ -138,87 +131,61 @@ add_library(lib_com ${libComSrcs} ${libComHeaders}) if(UNIX) target_link_libraries(lib_com PRIVATE m) endif() -target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug lib_util) -if(INCLUDE_SPLIT) - target_include_directories(lib_com PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug lib_isar lib_util) +target_include_directories(lib_com PRIVATE lib_lc3plus) file(GLOB libDebugSrcs "lib_debug/*.c") file(GLOB libDebugHeaders "lib_debug/*.h") add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders}) target_link_libraries(lib_debug lib_com) -target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend lib_util) +target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend lib_isar lib_util) file(GLOB libEncSrcs "lib_enc/*.c") file(GLOB libEncHeaders "lib_enc/*.h") add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) target_link_libraries(lib_enc lib_com lib_debug) -target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend lib_util ) -if(INCLUDE_SPLIT) - target_include_directories(lib_enc PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend lib_isar lib_util) +target_include_directories(lib_enc PRIVATE lib_lc3plus) -if(INCLUDE_SPLIT) - file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") - file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") - add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) - target_include_directories(lib_lc3plus PUBLIC lib_lc3plus) - target_link_libraries(lib_lc3plus lib_com) # For including options.h, which is needed for instrumentation to work correctly - if(WMOPS) - target_link_libraries(lib_lc3plus lib_debug) - endif() -endif() +file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") +file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") +add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) +target_include_directories(lib_lc3plus PUBLIC lib_lc3plus PRIVATE lib_com lib_debug) file(GLOB libRendSrcs "lib_rend/*.c") file(GLOB libRendHeaders "lib_rend/*.h") -if(NOT INCLUDE_SPLIT) - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitrenderer.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_Pred.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_RMSEnv.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_PerceptualModel.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.c$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.h$") -endif() add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) target_link_libraries(lib_rend lib_dec lib_com lib_debug lib_util) # Todo refactor: This dependency on lib_dec should be removed. -if(INCLUDE_SPLIT) - target_link_libraries(lib_rend lib_lc3plus) -endif() -target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc lib_util) +target_link_libraries(lib_rend lib_lc3plus lib_isar) +target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc lib_isar lib_util) file(GLOB libDecSrcs "lib_dec/*.c") file(GLOB libDecHeaders "lib_dec/*.h") add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) -target_link_libraries(lib_dec lib_com lib_rend lib_debug) -target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_util) +target_link_libraries(lib_dec lib_com lib_rend lib_debug lib_isar) +target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_isar lib_util) file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") -if(NOT INCLUDE_SPLIT) - list(FILTER libUtilSrcs EXCLUDE REGEX ".*lib_util\/.*split_rend.*\.c$") -endif() add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug lib_util) -if(INCLUDE_SPLIT) - target_include_directories(lib_util PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_util PRIVATE lib_lc3plus lib_isar) -if(INCLUDE_SPLIT) - if(NOT WMOPS) +if(NOT WMOPS) add_executable(ivas_lc3plus_unit_test ${CMAKE_SOURCE_DIR}/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c) - target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug) - endif() + target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug lib_isar) endif() +file(GLOB libISARSrcs "lib_isar/*.c") +file(GLOB libISARHeaders "lib_isar/*.h") + +add_library(lib_isar ${libISARSrcs} ${libISARHeaders}) +target_link_libraries(lib_isar lib_com lib_debug lib_lc3plus) # Todo refactor: This dependency on lib_dec should be removed. +target_include_directories(lib_isar PUBLIC lib_isar PRIVATE lib_enc lib_dec lib_rend) + + add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) if(WIN32) @@ -232,19 +199,22 @@ if(WIN32) endif() add_executable(IVAS_rend apps/renderer.c) -target_link_libraries(IVAS_rend lib_rend lib_util) +target_link_libraries(IVAS_rend lib_rend lib_util lib_isar) target_include_directories(IVAS_rend PRIVATE lib_enc lib_util) +add_executable(ISAR_post_rend apps/isar_post_rend.c) +target_link_libraries(ISAR_post_rend lib_isar lib_util) +target_include_directories(ISAR_post_rend PRIVATE lib_isar) + if(COPY_EXECUTABLES_FROM_BUILD_DIR) # Optionally copy executables to the same place where Make puts them (useful for tests that expect executables in specific places) add_custom_command(TARGET IVAS_cod POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET IVAS_dec POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") - if(INCLUDE_SPLIT) + add_custom_command(TARGET ISAR_post_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") if (NOT WMOPS) add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus") endif() - endif() endif() # Allow creating packages for CMake install diff --git a/Makefile b/Makefile index 51d711ae3d70bcc0c2f8e5be357b24ab059c94e8..63ac29842bb6109347cb23165b22538b037adb2d 100644 --- a/Makefile +++ b/Makefile @@ -6,25 +6,29 @@ SRC_LIBDEBUG = lib_debug SRC_LIBDEC = lib_dec SRC_LIBENC = lib_enc SRC_LIBREND = lib_rend +SRC_LIBISAR = lib_isar SRC_LC3PLUS = lib_lc3plus lib_lc3plus/fft SRC_LIBUTIL = lib_util SRC_APP = apps BUILD = build OBJDIR = obj -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) +SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBISAR) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) # Name of CLI binaries -CLI_APIDEC ?= IVAS_dec -CLI_APIENC ?= IVAS_cod -CLI_APIREND ?= IVAS_rend -LIB_LIBCOM ?= libivascom.a -LIB_LIBDEBUG ?= libivasdebug.a -LIB_LIBDEC ?= libivasdec.a -LIB_LIBENC ?= libivasenc.a -LIB_LIBREND ?= libivasrend.a -LIB_LC3PLUS ?= liblc3plus.a -LIB_LIBUTIL ?= libivasutil.a +CLI_APIDEC ?= IVAS_dec +CLI_APIENC ?= IVAS_cod +CLI_APIREND ?= IVAS_rend +CLI_APIPOSTREND ?= ISAR_post_rend +LIB_LIBCOM ?= libivascom.a +LIB_LIBDEBUG ?= libivasdebug.a +LIB_LIBDEC ?= libivasdec.a +LIB_LIBENC ?= libivasenc.a +LIB_LIBREND ?= libivasrend.a +LIB_LIBISAR ?= libisar.a +LIB_LC3PLUS ?= liblc3plus.a +LIB_LIBUTIL ?= libivasutil.a + # Default tool settings CC ?= gcc @@ -135,32 +139,31 @@ SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) -ifeq "$(INCLUDE_SPLIT)" "1" +SRCS_LIBISAR = $(foreach DIR,$(SRC_LIBISAR),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LC3PLUS = $(foreach DIR,$(SRC_LC3PLUS),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) -else -SRCS_LIBREND := $(filter-out $(SRCS_SPLIT_REND),$(SRCS_LIBREND)) -SRCS_LIBUTIL := $(filter-out $(SRCS_SPLIT_REND),$(SRCS_LIBUTIL)) -endif OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o)) OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o)) OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o)) OBJS_LIBENC = $(addprefix $(OBJDIR)/,$(SRCS_LIBENC:.c=.o)) OBJS_LIBREND = $(addprefix $(OBJDIR)/,$(SRCS_LIBREND:.c=.o)) +OBJS_LIBISAR = $(addprefix $(OBJDIR)/,$(SRCS_LIBISAR:.c=.o)) OBJS_LC3PLUS = $(addprefix $(OBJDIR)/,$(SRCS_LC3PLUS:.c=.o)) OBJS_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) OBJS_CLI_APIDEC = $(OBJDIR)/decoder.o OBJS_CLI_APIENC = $(OBJDIR)/encoder.o OBJS_CLI_APPREND = $(OBJDIR)/renderer.o +OBJS_CLI_APPPOSTREND = $(OBJDIR)/isar_post_rend.o DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS_LIBDEC:.c=.P) \ - $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LC3PLUS:.c=.P)) + $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LIBISAR:.c=.P) \ + $(SRCS_LC3PLUS:.c=.P)) ############################################################################### .PHONY: all clean -all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) +all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(CLI_APIPOSTREND) $(OBJDIR): $(QUIET)mkdir -p $(OBJDIR) @@ -168,24 +171,23 @@ $(OBJDIR): $(LIB_LIBCOM): $(OBJS_LIBCOM) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) +$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) $(QUIET_AR)$(AR) rcs $@ $^ +$(LIB_LIBISAR): $(OBJS_LIBISAR) + $(QUIET_AR)$(AR) rcs $@ $^ + $(LIB_LIBENC): $(OBJS_LIBENC) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBREND): $(OBJS_LIBREND) +$(LIB_LIBREND): $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LC3PLUS): $(OBJS_LC3PLUS) -ifeq "$(INCLUDE_SPLIT)" "1" $(QUIET_AR)$(AR) rcs $@ $^ -else - -endif $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(QUIET_AR)$(AR) rcs $@ $^ @@ -193,27 +195,22 @@ $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasenc -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIENC) -$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) -ifeq "$(INCLUDE_SPLIT)" "1" +$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(LIB_LIBISAR) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug -llc3plus $(LDLIBS) -o $(CLI_APIDEC) -else - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) -endif -$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) -ifeq "$(INCLUDE_SPLIT)" "1" - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) -else - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) -endif +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) $(LIB_LIBISAR) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -lisar -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) + +$(CLI_APIPOSTREND): $(OBJS_CLI_APPPOSTREND) $(LIB_LIBISAR) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPPOSTREND) -L. -lisar -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIPOSTREND) -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LC3PLUS) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(LIB_LIBUTIL) clean: $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(DEPS) $(QUIET)$(RM) $(DEPS:.P=.d) $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) - $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LC3PLUS) + $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(CLI_APIPOSTREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index f7a8d6f9e8c1a9d10d9a4f0b02195a48605c37c1..ac2e76b52f0224eefb2fb6c56cbd2a41be66812c 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -20,13 +20,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LC3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_lc3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" ProjectSection(SolutionItems) = preProject ..\.clang-format = ..\.clang-format EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_isar", "lib_isar.vcxproj", "{869A305E-D99E-4C3A-BDB3-AA57ABCCE619}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isar_post_rend", "isar_post_rend.vcxproj", "{12374ADC-0E5C-4FDD-B903-71D572413831}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -95,6 +99,18 @@ Global {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|Win32.ActiveCfg = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|Win32.Build.0 = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|x64.ActiveCfg = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|Win32.ActiveCfg = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|Win32.Build.0 = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|x64.ActiveCfg = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|Win32.ActiveCfg = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|Win32.Build.0 = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|x64.ActiveCfg = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|Win32.ActiveCfg = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|Win32.Build.0 = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index a2661ac082ab5863da17c592c360703e5e76f154..00e29933a4ad9d6b08c9a554c2a275ac7799ff89 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_dec;..\lib_util;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -113,7 +113,7 @@ Neither false false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -157,6 +157,9 @@ {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} false + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + {2fa8f384-0775-f3b7-f8c3-85209222fc70} false @@ -170,4 +173,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/isar_post_rend.vcxproj b/Workspace_msvc/isar_post_rend.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..170ff20545a4ac5c7d610daac49ba963ad4d88b4 --- /dev/null +++ b/Workspace_msvc/isar_post_rend.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + isar_post_rend + {12374ADC-0E5C-4FDD-B903-71D572413831} + isar_post_rend + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + ISAR_post_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + ISAR_post_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 8312a63fa5eaa36f2da888df44e01b7a1d866757..9706441d6d840d42b7da159d5ec3b9a68b1bf9fc 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -59,7 +59,7 @@ Disabled - ..\lib_util;..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -95,7 +95,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -205,6 +205,7 @@ + @@ -221,6 +222,8 @@ + + @@ -308,4 +311,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index a719959802cc618915d6e5023c8f2e9b38fb9eea..b7c9cc3bdb54a4ed12f99cf0334067da83e0728a 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -469,6 +469,10 @@ common_ivas_c + + common_ivas_c + + @@ -548,4 +552,4 @@ {b95b7bed-a666-4a00-9332-2b528638503e} - \ No newline at end of file + diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index cf9efaf458ebee6d284934fb4cb4a0a1edee2678..4f4803ac82801a63e1617bf94bd0e8bc3768c4e7 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_util;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -348,4 +348,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index f1ff59c863eb45cda0e18d776cb79dd2bffa49e2..91a19db89b490ce9ec3075b5d24a2dcf227c4994 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_util;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -112,7 +112,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -364,4 +364,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..2f089e3002947038a59c5c10454394cdb8d9247c --- /dev/null +++ b/Workspace_msvc/lib_isar.vcxproj @@ -0,0 +1,200 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_isar + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj index a2e45cb609fe6f11b23b55635ff59d69522ae5ea..55a291fa9c768769f213dac4423688e2db81f8e3 100644 --- a/Workspace_msvc/lib_lc3plus.vcxproj +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -65,7 +65,7 @@ Level3 - ..\lib_com;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) Disabled MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) @@ -84,7 +84,7 @@ Level3 - ..\lib_com;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) MaxSpeed MultiThreaded true @@ -182,4 +182,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index ce6ff51bf7f2c8c3c8efc7aad2f788fdb0e2bf73..fcb56e1d219e5632aa551ac9cdc3798c296c55a4 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_util;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -144,30 +144,11 @@ - - - - - - - - - - - - - - - - - - - @@ -198,8 +179,6 @@ - - @@ -207,9 +186,6 @@ - - - @@ -233,4 +209,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 72f1c9f7c46bebdfc2ddcf3bc315422476ed6040..37dc0515c5e7f6bec60b7ee85f1491b040035b08 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -55,7 +55,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) false @@ -79,7 +79,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) true @@ -101,6 +101,7 @@ + @@ -128,6 +129,7 @@ + @@ -163,4 +165,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 83f6afc4dc365881f6710241d9fa2f6e6f896777..0a7c72a16cac7af074424ab02179cb616f9b3e23 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -65,7 +65,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -110,7 +110,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -158,6 +158,9 @@ {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} false + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + {2FA8F384-0775-F3B7-F8C3-85209222FC70} false diff --git a/apps/decoder.c b/apps/decoder.c index c66982896d7f09aa601e4b418f656a785160959b..9cb609e53950feaf83252ecb01cace3c5dd82abf 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -46,9 +46,8 @@ #ifdef AMBISONICS_CONVENTIONS #include "ambi_convert.h" #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "aeid_file_reader.h" #include "split_render_file_read_write.h" -#endif #ifdef VARIABLE_SPEED_DECODING #include "tsm_scale_file_reader.h" #include @@ -93,6 +92,15 @@ static * Local structure for storing cmdln arguments *------------------------------------------------------------------------------------------*/ +typedef struct +{ + uint16_t *pID; + uint16_t *pValidity; + uint16_t count; + uint16_t selected; + uint16_t frameCounter; +} AcousticEnvironmentSequence; + typedef struct { char *inputBitstreamFilename; @@ -127,9 +135,7 @@ typedef struct float non_diegetic_pan_gain; bool renderConfigEnabled; char *renderConfigFilename; -#ifdef SPLIT_REND_WITH_HEAD_ROT char *outputMdFilename; -#endif IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; bool tsmEnabled; IVAS_RENDER_FRAMESIZE renderFramesize; @@ -144,7 +150,7 @@ typedef struct uint16_t tsmScale; #endif #endif - uint16_t acousticEnvironmentId; + AcousticEnvironmentSequence aeSequence; int16_t Opt_dpid_on; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; #ifdef AMBISONICS_CONVENTIONS @@ -160,11 +166,7 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, uint8_t *splitRendBitsBuf, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); -#else -static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); -#endif +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); #ifdef DEBUGGING @@ -186,9 +188,8 @@ int main( bool mainFailed = true; /* Assume main failed until cleanup is reached without errors */ DecArguments arg; ivas_error error = IVAS_ERR_UNKNOWN; -#ifdef SPLIT_REND_WITH_HEAD_ROT - uint8_t splitRendBitsBuf[IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; -#endif + ISAR_SPLIT_REND_BITS_DATA splitRendBits; + uint8_t splitRendBitsBuf[ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; /* Any handles that require cleanup must be declared here and initialized to NULL */ IVAS_DEC_HANDLE hIvasDec = NULL; @@ -221,6 +222,8 @@ int main( reset_mem( USE_BYTES ); #endif + splitRendBits.bits_buf = splitRendBitsBuf; + /*------------------------------------------------------------------------------------------* * Parse command-line arguments *------------------------------------------------------------------------------------------*/ @@ -267,7 +270,6 @@ int main( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { fprintf( stdout, "Output metadata file: %s\n", arg.outputWavFilename ); @@ -278,7 +280,6 @@ int main( fprintf( stdout, "Output metadata file: %s\n", arg.outputMdFilename ); } else -#endif { fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename ); } @@ -312,11 +313,7 @@ int main( if ( arg.enableHeadRotation ) { /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -416,11 +413,8 @@ int main( if ( arg.renderConfigEnabled ) { /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 ) { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -438,8 +432,9 @@ int main( *------------------------------------------------------------------------------------------*/ asked_frame_size = arg.renderFramesize; + uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, - arg.Opt_dpid_on, arg.acousticEnvironmentId, arg.delayCompensationEnabled + arg.Opt_dpid_on, aeID, arg.delayCompensationEnabled #ifdef AMBISONICS_CONVENTIONS , arg.sba_output_fmt @@ -465,13 +460,12 @@ int main( * Configure Split rendering *------------------------------------------------------------------------------------------*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT asked_frame_size = arg.renderFramesize; if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nSplit rendering configure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } @@ -483,7 +477,6 @@ int main( arg.enableHeadRotation = true; } -#endif /*------------------------------------------------------------------------------------------* * Configure VoIP mode @@ -612,20 +605,13 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && - arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 ) { fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); goto cleanup; } -#else - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - fprintf( stderr, "\nExternal Renderer Config is supported only for binaural output configurations. Exiting. \n\n" ); - goto cleanup; - } -#endif if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) { @@ -644,32 +630,38 @@ int main( fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); goto cleanup; } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - renderConfig.split_rend_config.dof == 0 ) ) + if ( ( error = RenderConfigReader_getDistanceAttenuation( renderConfigReader, renderConfig.distAtt ) ) != IVAS_ERR_OK ) { - arg.renderFramesize = asked_frame_size; + fprintf( stderr, "Failed to get Distance Attenuation \n\n" ); + goto cleanup; } - else + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; - } + if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && + ( renderConfig.split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) + { + arg.renderFramesize = asked_frame_size; + } + else + { + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; + } - if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( arg.renderFramesize != asked_frame_size ) - { - fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); + if ( arg.renderFramesize != asked_frame_size ) + { + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); + } } -#endif if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -679,12 +671,16 @@ int main( } else { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", arg.acousticEnvironmentId ); + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); goto cleanup; } renderConfig.roomAcoustics.override = true; } + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) arg.renderFramesize /* given in number of 5ms subframes */ * 5; + if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -841,11 +837,7 @@ int main( } else { -#ifdef SPLIT_REND_WITH_HEAD_ROT - error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, splitRendBitsBuf, hIvasDec, pcmBuf ); -#else - error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); -#endif + error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf ); } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -886,6 +878,11 @@ cleanup: free( pcmBuf ); + if ( arg.aeSequence.count > 0 ) + { + free( arg.aeSequence.pID ); + free( arg.aeSequence.pValidity ); + } #ifdef DEBUG_SBA_AUDIO_DUMP IVAS_DEC_GetSbaDebugParams( hIvasDec, &numOutChannels, &numTransportChannels, &pca_ingest_channels ); @@ -1000,7 +997,6 @@ static IVAS_AUDIO_CONFIG cmdline2config( { output_config = IVAS_AUDIO_CONFIG_BINAURAL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_CODED" ) == 0 ) { output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; @@ -1009,7 +1005,6 @@ static IVAS_AUDIO_CONFIG cmdline2config( { output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; } -#endif else if ( strcmp( argv_to_upper, "BINAURAL_ROOM_IR" ) == 0 ) { output_config = IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -1089,9 +1084,7 @@ static bool parseCmdlIVAS_dec( arg->sba_output_fmt = AMBI_FMT_ACN_SN3D; #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT arg->outputMdFilename = NULL; -#endif arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; @@ -1105,7 +1098,11 @@ static bool parseCmdlIVAS_dec( arg->tsmScaleFileName = NULL; #endif #endif - arg->acousticEnvironmentId = 65535; + arg->aeSequence.count = 0; + arg->aeSequence.pID = NULL; + arg->aeSequence.pValidity = NULL; + arg->aeSequence.selected = 0; + arg->aeSequence.frameCounter = 0; for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { arg->directivityPatternId[i] = 65535; @@ -1436,19 +1433,17 @@ static bool parseCmdlIVAS_dec( } i += 2; } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( strcmp( argv_to_upper, "-OM" ) == 0 ) { arg->outputMdFilename = argv[i + 1]; if ( arg->outputMdFilename[0] == '\0' ) { - fprintf( stderr, "Error: output metadata file path not specified\n\n" ); + fprintf( stderr, "Error: Split rendering output metadata file path not specified\n\n" ); usage_dec(); return false; } i += 2; } -#endif else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 ) { i++; @@ -1510,11 +1505,40 @@ static bool parseCmdlIVAS_dec( if ( !is_digits_only( argv[i] ) ) { - fprintf( stdout, "Error: Invalid acoustic environment ID specified: %s\n\n", argv[i] ); - usage_dec(); - return false; + aeidFileReader *aeidReader = NULL; + + if ( aeidFileReader_open( argv[i], &aeidReader ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open aeid file %s \n", argv[i] ); + usage_dec(); + return false; + } + + if ( aeidFileReading( aeidReader, &arg->aeSequence.count, &arg->aeSequence.pID, &arg->aeSequence.pValidity ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError while reading aeid from %s\n", argv[i] ); + usage_dec(); + return false; + } + + aeidFileReader_close( &aeidReader ); + + i++; + } + else + { + /* A single acoustic environment */ + if ( NULL == ( arg->aeSequence.pID = malloc( sizeof( uint16_t ) ) ) || + NULL == ( arg->aeSequence.pValidity = malloc( sizeof( uint16_t ) ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", argv[i] ); + usage_dec(); + return false; + } + arg->aeSequence.count = 1; + arg->aeSequence.pID[0] = (int16_t) atoi( argv[i++] ); + arg->aeSequence.pValidity[0] = 0; } - arg->acousticEnvironmentId = (int16_t) atoi( argv[i++] ); } else if ( strcmp( argv_to_upper, "-DPID" ) == 0 ) { @@ -1606,6 +1630,13 @@ static bool parseCmdlIVAS_dec( usage_dec(); return false; } + + if ( arg->outputMdFilename != NULL && arg->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + fprintf( stderr, "Error: Output split rendering metadata file is supported for BINAURAL_SPLIT_PCM output config. only\n\n" ); + usage_dec(); + return false; + } } else { @@ -1682,13 +1713,8 @@ static void usage_dec( void ) fprintf( stdout, "Mandatory parameters:\n" ); fprintf( stdout, "---------------------\n" ); -#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT\n" ); -#else - fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); - fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT\n" ); -#endif fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" ); fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" ); fprintf( stdout, " layout file. See readme.txt for details.\n" ); @@ -1738,9 +1764,7 @@ static void usage_dec( void ) fprintf( stdout, "-rvf File : Reference vector specified by external trajectory File\n" ); fprintf( stdout, " works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes\n" ); fprintf( stdout, "-render_config File : Renderer configuration File\n" ); -#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stdout, "-om File : Metadata output File for BINAURAL_SPLIT_PCM OutputConf (only for Fs = 48 kHz)\n" ); -#endif fprintf( stdout, "-non_diegetic_pan P : panning mono non-diegetic sound to stereo with paning P, -90<= P <=90,\n" ); fprintf( stdout, " left or l or 90->left, right or r or -90->right, center or c or 0->middle\n" ); #ifdef DEBUGGING @@ -1757,7 +1781,9 @@ static void usage_dec( void ) fprintf( stdout, " output configuration. ID1, ID2, ID3, ID4 specify the directivity pattern IDs used for\n" ); fprintf( stdout, " ISMs 1,2,3 and 4 respectively. This options needs to be accompanied by a render_config file,\n" ); fprintf( stdout, " otherwise a default directivity pattern is used.\n" ); - fprintf( stdout, "-aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration\n" ); + fprintf( stdout, "-aeid ID | File : Acoustic environment ID (number > 0)\n" ); + fprintf( stdout, " alternatively, it can be a text file where each line contains \"ID duration\"\n" ); + fprintf( stdout, " for BINAURAL_ROOM_REVERB output configuration.\n" ); fprintf( stdout, "-level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. \n" ); fprintf( stdout, " Currently, all values default to level 3 (full functionality).\n" ); fprintf( stdout, "-q : Quiet mode, no frame counter\n" ); @@ -1795,15 +1821,11 @@ static int16_t app_own_random( int16_t *seed ) *---------------------------------------------------------------------*/ static ivas_error initOnFirstGoodFrame( - IVAS_DEC_HANDLE hIvasDec, /* i/o: */ - const DecArguments arg, /* i : */ - const int16_t numInitialBadFrames, /* i : */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t *numOutSamples, /* i/o: */ - int16_t *vec_pos_len, /* i/o: */ -#else - const uint16_t numOutSamples, /* i : */ -#endif + IVAS_DEC_HANDLE hIvasDec, /* i/o: */ + const DecArguments arg, /* i : */ + const int16_t numInitialBadFrames, /* i : */ + int16_t *numOutSamples, /* i/o: */ + int16_t *vec_pos_len, /* i/o: */ int16_t *pFullDelayNumSamples, /* o : */ int16_t *pRemainingDelayNumSamples, /* o : */ int32_t *delayTimeScale, /* o : */ @@ -1812,14 +1834,10 @@ static ivas_error initOnFirstGoodFrame( MasaFileWriter **ppMasaWriter, /* o : */ IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - uint16_t *pNumObj, /* o : */ - SplitFileReadWrite **splitRendWriter -#else - uint16_t *pNumObj /* o : */ -#endif -) + uint16_t *pNumObj, /* o : */ + SplitFileReadWrite **splitRendWriter ) { + int16_t isSplitRend, isSplitCoded; ivas_error error = IVAS_ERR_UNKNOWN; /* Now delay, number of output channels and frame size are known */ @@ -1829,12 +1847,22 @@ static ivas_error initOnFirstGoodFrame( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( ( error = IVAS_DEC_is_split_rendering_enabled( hIvasDec, &isSplitRend ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_enabled, code: %d\n", error ); + return error; + } + + if ( ( error = IVAS_DEC_is_split_rendering_coded_out( hIvasDec, &isSplitCoded ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_coded_out, code: %d\n", error ); + return error; + } + + if ( isSplitRend ) { pFullDelayNumSamples[0] = 0; } -#endif if ( !arg.delayCompensationEnabled ) { @@ -1856,12 +1884,16 @@ static ivas_error initOnFirstGoodFrame( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( isSplitRend ) { /* Open split rendering metadata writer */ int16_t delayNumSamples_temp[3]; int32_t delayTimeScale_temp; + ISAR_SPLIT_REND_CODEC splitRendCodec; + int16_t splitRendCodecFrameSizeMs; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + int16_t splitRendIsarFrameSizeMs; + int16_t lc3plusHighRes; if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) { @@ -1869,9 +1901,15 @@ static ivas_error initOnFirstGoodFrame( return error; } - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( ( error = IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec, &splitRendCodec, &poseCorrection, &splitRendIsarFrameSizeMs, &splitRendCodecFrameSizeMs, &lc3plusHighRes ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + return error; + } + + if ( isSplitCoded ) { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs, splitRendIsarFrameSizeMs, arg.output_Fs, lc3plusHighRes ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1879,7 +1917,13 @@ static ivas_error initOnFirstGoodFrame( } else { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( arg.outputMdFilename == NULL ) + { + fprintf( stderr, "\nOutput split rendering metadata file not specified\n" ); + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs, splitRendIsarFrameSizeMs, arg.output_Fs, lc3plusHighRes ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1887,37 +1931,34 @@ static ivas_error initOnFirstGoodFrame( } } - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( !isSplitCoded ) { -#endif /* Open audio writer and write all previously skipped bad frames now that frame size is known */ if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif int16_t *zeroBuf = malloc( pcmFrameSize * sizeof( int16_t ) ); memset( zeroBuf, 0, pcmFrameSize * sizeof( int16_t ) ); for ( int16_t i = 0; i < numInitialBadFrames; ++i ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( *splitRendWriter != NULL ) { - IVAS_SPLIT_REND_BITS_DATA splitRendBitsZero; + ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero; splitRendBitsZero.bits_buf = NULL; splitRendBitsZero.bits_read = 0; splitRendBitsZero.bits_written = 0; splitRendBitsZero.buf_len = 0; - splitRendBitsZero.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - splitRendBitsZero.pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - splitRendBitsZero.codec_frame_size_ms = 20; + splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBitsZero.codec_frame_size_ms = 0; + splitRendBitsZero.isar_frame_size_ms = 20; - if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written, -1, IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, splitRendBitsZero.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); return error; @@ -1925,19 +1966,10 @@ static ivas_error initOnFirstGoodFrame( } else { -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( *pRemainingDelayNumSamples < *numOutSamples ) -#else - if ( *pRemainingDelayNumSamples < numOutSamples ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) -#else - if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "\nOutput audio file writer error\n" ); return error; @@ -1946,15 +1978,9 @@ static ivas_error initOnFirstGoodFrame( } else { -#ifdef SPLIT_REND_WITH_HEAD_ROT *pRemainingDelayNumSamples -= *numOutSamples; -#else - *pRemainingDelayNumSamples -= numOutSamples; -#endif } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } free( zeroBuf ); @@ -2041,7 +2067,6 @@ static ivas_error initOnFirstGoodFrame( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( *splitRendWriter != NULL ) { if ( numOutSamples == NULL || vec_pos_len == NULL ) @@ -2061,7 +2086,6 @@ static ivas_error initOnFirstGoodFrame( return error; } } -#endif return IVAS_ERR_OK; } @@ -2080,9 +2104,7 @@ static ivas_error decodeG192( RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, -#ifdef SPLIT_REND_WITH_HEAD_ROT - uint8_t *splitRendBitsBuf, -#endif + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -2118,9 +2140,44 @@ static ivas_error decodeG192( IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; int16_t vec_pos_update, vec_pos_len; -#ifdef SPLIT_REND_WITH_HEAD_ROT SplitFileReadWrite *splitRendWriter = NULL; -#endif + int16_t isSplitRend, isSplitCoded; + + if ( ( error = IVAS_DEC_is_split_rendering_enabled( hIvasDec, &isSplitRend ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_enabled, code: %d\n", error ); + return error; + } + + if ( ( error = IVAS_DEC_is_split_rendering_coded_out( hIvasDec, &isSplitCoded ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_is_split_rendering_coded_out, code: %d\n", error ); + return error; + } + + IVAS_RENDER_CONFIG_DATA renderConfig; + RenderConfigReader *renderConfigReader = NULL; + + if ( arg.renderConfigEnabled ) + { + if ( ( error = RenderConfigReader_open( arg.renderConfigFilename, &renderConfigReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", arg.renderConfigFilename ); + 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 ) ); + goto cleanup; + } + + if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); + goto cleanup; + } + } for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -2255,7 +2312,6 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( headRotReader == NULL ) { for ( i = 0; i < num_subframes; i++ ) @@ -2271,7 +2327,6 @@ static ivas_error decodeG192( } else { -#endif for ( i = 0; i < num_subframes; i++ ) { if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) @@ -2280,17 +2335,11 @@ static ivas_error decodeG192( goto cleanup; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif for ( i = 0; i < num_subframes; i++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2331,6 +2380,36 @@ static ivas_error decodeG192( { if ( needNewFrame ) { + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && renderConfigReader != NULL && + arg.aeSequence.count > 0 && arg.aeSequence.pValidity[arg.aeSequence.selected] != 0 ) + { + if ( ++arg.aeSequence.frameCounter >= arg.aeSequence.pValidity[arg.aeSequence.selected] ) + { + if ( ++arg.aeSequence.selected >= arg.aeSequence.count ) + { + arg.aeSequence.selected = 0; + } + arg.aeSequence.frameCounter = 0; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.aeSequence.pID[arg.aeSequence.selected], &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) + { + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid acoustic environment configuratoin parameters\n\n" ); + goto cleanup; + } + } + else + { + fprintf( stderr, "Failed to get acoustic environment with ID %d\n\n", arg.aeSequence.pID[arg.aeSequence.selected] ); + 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 ) ); + goto cleanup; + } + } + } #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING if ( arg.tsmScaleFileEnabled ) @@ -2384,10 +2463,9 @@ static ivas_error decodeG192( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( isSplitRend ) { - if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBitsBuf, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2398,23 +2476,14 @@ static ivas_error decodeG192( } else { -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) - -#else - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) - -#endif { fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif if ( needNewFrame ) { frame++; @@ -2448,11 +2517,7 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) -#else - if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) -#endif { goto cleanup; } @@ -2466,27 +2531,17 @@ static ivas_error decodeG192( /* Write current frame */ if ( decodedGoodFrame ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( isSplitRend ) { - IVAS_SPLIT_REND_BITS_DATA splitRendBits; - - if ( ( error = IVAS_DEC_GetSplitRendBits( hIvasDec, &splitRendBits ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError in IVAS_DEC_SplitRendBits: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - - if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written, splitRendBits.codec, splitRendBits.pose_correction, splitRendBits.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits->bits_buf, &splitRendBits->bits_read, &splitRendBits->bits_written ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); goto cleanup; } } - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( !isSplitCoded ) { -#endif if ( delayNumSamples < nOutSamples ) { if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) @@ -2500,9 +2555,7 @@ static ivas_error decodeG192( { delayNumSamples -= nOutSamples; } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } /* Write ISm metadata to external file(s) */ @@ -2623,11 +2676,7 @@ static ivas_error decodeG192( goto cleanup; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2635,11 +2684,7 @@ static ivas_error decodeG192( } /* decode and get samples */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2757,18 +2802,15 @@ static ivas_error decodeG192( *------------------------------------------------------------------------------------------*/ memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); -#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( afWriter != NULL ) { -#endif if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); goto cleanup; } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif /*------------------------------------------------------------------------------------------* * Close files and deallocate resources @@ -2778,9 +2820,8 @@ static ivas_error decodeG192( cleanup: -#ifdef SPLIT_REND_WITH_HEAD_ROT + RenderConfigReader_close( &renderConfigReader ); split_rend_reader_writer_close( &splitRendWriter ); -#endif AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); #ifdef DEBUGGING @@ -3132,7 +3173,6 @@ static ivas_error decodeVoIP( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( headRotReader == NULL ) { for ( i = 0; i < num_subframes; i++ ) @@ -3148,7 +3188,6 @@ static ivas_error decodeVoIP( } else { -#endif for ( i = 0; i < num_subframes; i++ ) { if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) @@ -3158,18 +3197,11 @@ static ivas_error decodeVoIP( goto cleanup; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif for ( i = 0; i < num_subframes; i++ ) { - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - DEFAULT_AXIS -#endif - ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -3256,19 +3288,10 @@ static ivas_error decodeVoIP( /* decode and get samples */ - -#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SUPPORT_JBM_TRACEFILE if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) -#endif -#else -#ifdef SUPPORT_JBM_TRACEFILE - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) -#endif #endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -3305,15 +3328,10 @@ static ivas_error decodeVoIP( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT SplitFileReadWrite *splitRendWriter = NULL; if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) -#else - if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, - &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) -#endif { goto cleanup; } @@ -3418,11 +3436,7 @@ static ivas_error decodeVoIP( int16_t nSamplesFlushed = 0; /* decode and get samples */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..752618406c7ebe5aafadd330e264ddb30b498863 --- /dev/null +++ b/apps/isar_post_rend.c @@ -0,0 +1,1252 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "lib_isar_post_rend.h" + + +#include +#include +#include +#include "audio_file_reader.h" +#include "audio_file_writer.h" +#include "cmdl_tools.h" +#include "cmdln_parser.h" +#include "render_config_reader.h" +#include "rotation_file_reader.h" +#include "split_render_file_read_write.h" +#include "split_rend_bfi_file_reader.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#define WMC_TOOL_SKIP + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define POST_REND_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) + +#define ISAR_MAX16B_FLT 32767.0f +#define ISAR_MIN16B_FLT ( -32768.0f ) + +#if !defined( DEBUGGING ) && !defined( WMOPS ) +static +#endif + int32_t frame = 0; + +#ifdef _WIN32 +#define SEP_FOLDER '\\' +#else +#define SEP_FOLDER '/' +#endif + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; + int32_t inputChannelIndex; + float gain_dB; +} RendererInput; + +typedef struct +{ + RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; + uint16_t numBinBuses; +} InputConfig; + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; +} OutputConfig; + +typedef struct +{ + char executableName[POST_REND_MAX_CLI_ARG_LENGTH]; + char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + int32_t sampleRate; + InputConfig inConfig; + OutputConfig outConfig; + char inMetadataFilePaths[RENDERER_MAX_ISAR_MD_INPUTS][POST_REND_MAX_CLI_ARG_LENGTH]; + int16_t numInMetadataFiles; + char headRotationFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char splitRendBFIFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + ISAR_POST_REND_COMPLEXITY_LEVEL complexityLevel; + bool delayCompensationEnabled; + bool quietModeEnabled; + bool sceneDescriptionInput; + IVAS_RENDER_FRAMESIZE render_framesize; +} CmdlnArgs; + +typedef enum +{ + CmdLnOptionId_inputFile = 1, + CmdLnOptionId_inputFormat, + CmdLnOptionId_outputFile, + CmdLnOptionId_sampleRate, + CmdLnOptionId_trajFile, + CmdLnOptionId_orientationTracking, + CmdLnOptionId_complexityLevel, + CmdLnOptionId_noDelayCmp, + CmdLnOptionId_quietModeEnabled, + CmdLnOptionId_inputMetadata, + CmdLnOptionId_listFormats, + CmdLnOptionId_SplitRendBFIFile, + CmdLnOptionId_framing, +} CmdLnOptionId; + +static const CmdLnParser_Option cliOptions[] = { + { + .id = CmdLnOptionId_inputFile, + .match = "input_file", + .matchShort = "i", + .description = "Path to the input file (WAV, raw PCM or scene description file)", + }, + { + .id = CmdLnOptionId_inputFormat, + .match = "input_format", + .matchShort = "if", + .description = "Audio format of input file (e.g. BINAURAL_SPLIT_PCM, use -l for a list)", + }, + { + .id = CmdLnOptionId_inputMetadata, + .match = "input_metadata", + .matchShort = "im", + .description = "Space-separated list of path to metadata files for BINAURAL_SPLIT_PCM input mode", + }, + { + .id = CmdLnOptionId_outputFile, + .match = "output_file", + .matchShort = "o", + .description = "Path to the output file", + }, + { + .id = CmdLnOptionId_sampleRate, + .match = "sample_rate", + .matchShort = "fs", + .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs", + }, + { + .id = CmdLnOptionId_trajFile, + .match = "trajectory_file", + .matchShort = "T", + .description = "Head rotation trajectory file for simulation of head tracking", + }, + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, + { + .id = CmdLnOptionId_noDelayCmp, + .match = "no_delay_compensation", + .matchShort = "no_delay_cmp", + .description = "[flag] Turn off delay compensation", + }, + { + .id = CmdLnOptionId_complexityLevel, + .match = "complexity_level", + .matchShort = "level", + .description = "Complexity level, level = (1, 2, 3), will be defined after characterisation.", + }, + { + .id = CmdLnOptionId_quietModeEnabled, + .match = "quiet", + .matchShort = "q", + .description = "[flag] Limit printouts to terminal", + }, + { + .id = CmdLnOptionId_listFormats, + .match = "list", + .matchShort = "l", + .description = "List supported audio formats", + }, + { + .id = CmdLnOptionId_framing, + .match = "framing", + .matchShort = "fr", + .description = "Set Render audio framing.", + }, +}; + + +/*------------------------------------------------------------------------------------------* + * Local function prototypes + *------------------------------------------------------------------------------------------*/ + +static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); + +static void printSupportedAudioConfigs( void ); + +static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); + +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); + + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static ISAR_POST_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( + IVAS_REND_AudioBuffer buffer, + const int16_t chBeginIdx, + const int16_t numChannels ) +{ + ISAR_POST_REND_ReadOnlyAudioBuffer subBuffer; + + subBuffer.config = buffer.config; + subBuffer.config.numChannels = numChannels; + subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; + + return subBuffer; +} + + +static int16_t getTotalNumInChannels( + ISAR_POST_REND_HANDLE hIsarPostRend, + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] ) +{ + int16_t totalNumInChannels = 0; + int16_t i, numInputChannels; + ivas_error error; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + if ( splitBinIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + return totalNumInChannels; +} + +static const CmdLnParser_Option *findOptionById( + const int32_t id ) +{ + for ( int32_t i = 0; i < numCliOptions; ++i ) + { + if ( cliOptions[i].id == id ) + { + return &cliOptions[i]; + } + } + + return NULL; +} + +static bool parseInConfig( + const char *inFormatStr, + InputConfig *inConfig, + bool *sceneDescriptionInput ) +{ + char charBuf[FILENAME_MAX]; + + /* Initialize input config struct */ + inConfig->numBinBuses = 0; + + /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ + strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + if ( strcmp( charBuf, "META" ) == 0 ) + { + *sceneDescriptionInput = true; + /* Parsing the file will be done later. At this point the actual file path + * may not be known as command line parameters are still being parsed. */ + return true; + } + + /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */ + IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr ); + switch ( audioConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + inConfig->numBinBuses = 1; + inConfig->binBuses[0].audioConfig = audioConfig; + inConfig->binBuses[0].inputChannelIndex = 0; + inConfig->binBuses[0].gain_dB = 0.0f; + break; + default: + { + /* Default case covers formats that are defined in the AUDIO_CONFIG enum, + * but cannot be used at input, e.g. BINAURAL */ + const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats ); + fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match ); + return false; + } + } + + return true; +} + + +static bool parseRenderFramesize( + char *value, + IVAS_RENDER_FRAMESIZE *render_framesize ) +{ + int32_t tmp; + + *render_framesize = IVAS_RENDER_FRAMESIZE_UNKNOWN; + if ( !is_digits_only( value ) ) + { + return false; + } + tmp = (int32_t) strtol( value, NULL, 0 ); + switch ( (int16_t) tmp ) + { + case 5: + *render_framesize = IVAS_RENDER_FRAMESIZE_5MS; + break; + case 10: + *render_framesize = IVAS_RENDER_FRAMESIZE_10MS; + break; + case 20: + *render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + break; + default: + return false; + } + + return true; +} + + +static IVAS_AUDIO_CONFIG parseAudioConfig( + const char *configString ) +{ + char charBuf[25]; + charBuf[24] = '\0'; + + strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + + if ( strcmp( charBuf, "BINAURAL" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } + return IVAS_AUDIO_CONFIG_INVALID; +} + + +static bool checkRequiredArgs( + CmdlnArgs args ) +{ + const CmdLnParser_Option *tmpOption; + + /* Check required arguments */ + bool missingRequiredArg = false; + if ( isEmptyString( args.inputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_inputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + + const bool singleInputSpecified = ( args.inConfig.numBinBuses != 0 ); + + if ( !args.sceneDescriptionInput && !singleInputSpecified ) + { + /* Neither scene description input nor single-type input was specified on command line */ + tmpOption = findOptionById( CmdLnOptionId_inputFormat ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( isEmptyString( args.outputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_outputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( args.sampleRate == 0 ) + { + tmpOption = findOptionById( CmdLnOptionId_sampleRate ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( missingRequiredArg ) + { + CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions ); + } + + return !missingRequiredArg; +} + + +static CmdlnArgs defaultArgs( + const char *executableName ) +{ + CmdlnArgs args; + + strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH ); + clearString( args.inputFilePath ); + clearString( args.outputFilePath ); + args.sampleRate = 0; + + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID; + + for ( int32_t i = 0; i < RENDERER_MAX_ISAR_MD_INPUTS; ++i ) + { + clearString( args.inMetadataFilePaths[i] ); + } + args.numInMetadataFiles = 0; + + clearString( args.headRotationFilePath ); + clearString( args.splitRendBFIFilePath ); + + args.delayCompensationEnabled = true; + args.quietModeEnabled = false; + args.sceneDescriptionInput = false; + + args.render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + + return args; +} + + +static void parseOption( + const int32_t optionId, + char **optionValues, + const int16_t numOptionValues, + void *pOutputStruct ) +{ + CmdlnArgs *args = pOutputStruct; + + switch ( optionId ) + { + case CmdLnOptionId_listFormats: + assert( numOptionValues == 0 ); + printSupportedAudioConfigs(); + exit( 0 ); + case CmdLnOptionId_inputFile: + assert( numOptionValues == 1 ); + strncpy( args->inputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_inputFormat: + assert( numOptionValues == 1 ); + if ( !parseInConfig( optionValues[0], &args->inConfig, &args->sceneDescriptionInput ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + break; + case CmdLnOptionId_inputMetadata: + assert( numOptionValues <= RENDERER_MAX_ISAR_MD_INPUTS ); + for ( int16_t i = 0; i < numOptionValues; ++i ) + { + strncpy( args->inMetadataFilePaths[i], optionValues[i], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + } + args->numInMetadataFiles = numOptionValues; + break; + case CmdLnOptionId_outputFile: + assert( numOptionValues == 1 ); + strncpy( args->outputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_sampleRate: + assert( numOptionValues == 1 ); + args->sampleRate = (int32_t) ( strtol( optionValues[0], NULL, 10 ) * 1000 ); + if ( args->sampleRate == 0 ) + { + fprintf( stderr, "Invalid sampling rate specified\n" ); + exit( -1 ); + } + break; + case CmdLnOptionId_trajFile: + assert( numOptionValues == 1 ); + strncpy( args->headRotationFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_complexityLevel: + assert( numOptionValues == 1 ); + args->complexityLevel = (int32_t) ( strtol( optionValues[0], NULL, 10 ) ); + if ( args->complexityLevel < ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel > ISAR_POST_REND_COMPLEXITY_LEVEL_THREE ) + { + fprintf( stdout, "Invalid complexity level specified.\n" ); + exit( -1 ); + } + else if ( args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_TWO ) + { + fprintf( stdout, "Complexity levels 1 and 2 will be defined after characterisation - default to level 3 (full functionality).\n" ); + } + break; + case CmdLnOptionId_noDelayCmp: + assert( numOptionValues == 0 ); + args->delayCompensationEnabled = false; + break; + case CmdLnOptionId_quietModeEnabled: + assert( numOptionValues == 0 ); + args->quietModeEnabled = true; + break; + case CmdLnOptionId_framing: + assert( numOptionValues == 1 ); + if ( !parseRenderFramesize( optionValues[0], &args->render_framesize ) ) + { + fprintf( stderr, "Unknown or invalid option for frame size: %s\n", optionValues[0] ); + exit( -1 ); + } + + break; + default: + assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); + break; + } + + return; +} + + +static CmdlnArgs parseCmdlnArgs( + const int argc, + char **argv ) +{ + CmdlnArgs args = defaultArgs( argv[0] ); + + if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + if ( !checkRequiredArgs( args ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + return args; +} + + +static void printSupportedAudioConfigs( void ) +{ + uint16_t i; + const char *supportedFormats[] = { + "BINAURAL (output only)", + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CODED", + }; + + fprintf( stdout, "Supported audio formats:\n" ); + for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ ) + { + fprintf( stdout, "%s\n", supportedFormats[i] ); + } + + return; +} + + +/*--------------------------------------------------------------------------* + * convertInputBuffer() + * + * Convert input buffer from WAV/PCM file (int16_t, interleaved) to a format + * accepted by the renderer (float, packed) + *--------------------------------------------------------------------------*/ + +static void convertInputBuffer( + const int16_t *intBuffer, + const int16_t numIntSamplesPerChannel, + const int16_t numFloatSamplesPerChannel, + const int16_t numChannels, + float *floatBuffer ) +{ + int16_t chnl, smpl, i; + + i = 0; + + for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + if ( i < numIntSamplesPerChannel ) + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + } + else + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + } + + ++i; + } + } + + return; +} + + +/*--------------------------------------------------------------------------* + * convertOutputBuffer() + * + * Convert output buffer from the renderer (float, packed) to a format ready + * for writing to a WAV/PCM file (int16_t, interleaved) + *--------------------------------------------------------------------------*/ + +static void convertOutputBuffer( + const float *floatBuffer, + const int16_t numSamplesPerChannel, + const int16_t numChannels, + int16_t *intBuffer ) +{ + int16_t chnl, smpl, i; + float temp; + + i = 0; + + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; + temp = (float) floor( temp + 0.5f ); + if ( temp > ISAR_MAX16B_FLT ) + { + temp = ISAR_MAX16B_FLT; + } + else if ( temp < ISAR_MIN16B_FLT ) + { + temp = ISAR_MIN16B_FLT; + } + intBuffer[i] = (int16_t) temp; + + ++i; + } + } + + return; +} + + +/*------------------------------------------------------------------------------------------* + * main() + * + * Main ISAR post renderer function for command-line interface + *------------------------------------------------------------------------------------------*/ + +int main( + int argc, + char **argv ) +{ + ISAR_POST_REND_HANDLE hIsarPostRend; + RotFileReader *headRotReader = NULL; + RotFileReader *externalOrientationFileReader = NULL; + SplitRendBFIFileReader *splitRendBFIReader = NULL; + AudioFileReader *audioReader = NULL; + AudioFileWriter *audioWriter; + int32_t inBufferSize; + int32_t outBufferSize; + int32_t bitsBufferSize; + int16_t *inpInt16Buffer; + float *inFloatBuffer; + int16_t *outInt16Buffer; + float *outFloatBuffer; + uint8_t *bitsBufferData = NULL; + IVAS_REND_AudioBuffer inBuffer; + IVAS_REND_AudioBuffer outBuffer; + ISAR_POST_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + char audioFilePath[FILENAME_MAX]; + int16_t numSamplesRead; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig = 0; + int16_t zeroPad = 0; + int16_t zeroPadToWrite = 0; + int32_t delayTimeScale = 0; + int16_t i, numChannels; + ivas_error error = IVAS_ERR_OK; + bool splitBinNeedsNewFrame = true; + +#ifdef WMOPS + reset_wmops(); + reset_mem( USE_BYTES ); +#endif + + hSplitRendFileReadWrite = NULL; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plusHighRes = 0; + + /*------------------------------------------------------------------------------------------* + * Parse command-line arguments + *------------------------------------------------------------------------------------------*/ + + CmdlnArgs args = parseCmdlnArgs( argc, argv ); + + convert_backslash( args.inputFilePath ); + convert_backslash( args.outputFilePath ); + convert_backslash( args.headRotationFilePath ); + + /*------------------------------------------------------------------------------------------* + * Open head-rotation file + *------------------------------------------------------------------------------------------*/ + + if ( !isEmptyString( args.headRotationFilePath ) ) + { + if ( RotationFileReader_open( args.headRotationFilePath, &headRotReader ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", args.headRotationFilePath ); + exit( -1 ); + } + } + + /*------------------------------------------------------------------------------------------* + * Open BFI file + *------------------------------------------------------------------------------------------*/ + + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } + + /*------------------------------------------------------------------------------------------* + * Open input files + *------------------------------------------------------------------------------------------*/ + + int32_t inFileSampleRate = 0; + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); + hSplitRendFileReadWrite = NULL; + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inMetadataFilePaths[0], + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms, + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); + exit( -1 ); + } + + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } + } + + /*if split renderer is running in post renderer mode*/ + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inputFilePath, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms, + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); + exit( -1 ); + } + audioReader = NULL; + } + + if ( audioReader != NULL ) + { + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + } + else if ( hSplitRendFileReadWrite == NULL ) + { + inFileSampleRate = args.sampleRate; + } + + switch ( error ) + { + case IVAS_ERR_OK: + /* If sampling rate not given on command line, use the one from SR file */ + if ( args.sampleRate == 0 ) + { + args.sampleRate = inFileSampleRate; + } + /* else if sampling rate given on command line, compare with wav file */ + else if ( inFileSampleRate != args.sampleRate ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath ); + exit( -1 ); + } + break; + case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */ + if ( args.sampleRate == 0 ) + { + fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" ); + exit( -1 ); + } + break; + default: + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t inFileNumChannels = 0; + if ( audioReader != NULL ) + { + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + /*------------------------------------------------------------------------------------------* + * Open ISAR handle + *------------------------------------------------------------------------------------------*/ + + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_BINAURAL; + if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0.0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + /*------------------------------------------------------------------------------------------* + * Configuration + *------------------------------------------------------------------------------------------*/ + + if ( ( error = ISAR_POST_REND_InitConfig( hIsarPostRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Renderer Config Init: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( args.inConfig.numBinBuses > 0 ) + { + if ( ( error = ISAR_REND_SetSplitRendBitstreamHeader( hIsarPostRend, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms, + bitsBuffer.config.isar_frame_size_ms, + bitsBuffer.config.lc3plusHighRes ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in getting split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + splitBinIds[i] = 0u; + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = ISAR_POST_REND_AddInput( hIsarPostRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + const int16_t totalNumInChannels = getTotalNumInChannels( hIsarPostRend, splitBinIds ); + if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) + { + fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); + exit( -1 ); + } + + int16_t numOutChannels = 2; + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } + + /*------------------------------------------------------------------------------------------* + * Allocate processing buffers + *------------------------------------------------------------------------------------------*/ + + inBufferSize = frameSize_smpls * totalNumInChannels; + outBufferSize = frameSize_smpls * numOutChannels; + inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); + + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); + + inBuffer.config.is_cldfb = 0; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; + inBuffer.data = inFloatBuffer; + + outBuffer.config.is_cldfb = 0; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data = outFloatBuffer; + + memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); + + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; + + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the ISAR post renderer ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n\n-- Start the ISAR post renderer (quiet mode) --\n\n" ); + } + + /*------------------------------------------------------------------------------------------* + * Loop for every frame of data + * - Read the input data + * - Run the post-rendering + * - Write the data into output file + *------------------------------------------------------------------------------------------*/ + + while ( 1 ) + { + int16_t num_in_channels; + num_in_channels = inBuffer.config.numChannels; + + numSamplesRead = 0; + if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) + { + ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten ); + if ( error_tmp != IVAS_ERR_OK ) + { + if ( error_tmp == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + exit( -1 ); + } + } + } + + if ( audioReader != NULL ) + { + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } + } + + if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + { + /* end of input data */ + break; + } + + /* Convert from int to float and from interleaved to packed */ + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); + + int16_t num_subframes, sf_idx; + num_subframes = (int16_t) args.render_framesize; + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) + { + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + IVAS_QUATERNION headRot; + IVAS_VECTOR3 Pos; + + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetHeadRotation( hIsarPostRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + else + { + fprintf( stderr, "Head Rotation should be enabled in post renderer\n" ); + exit( -1 ); + } + + /* Read from split renderer bfi file if specified */ + if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) + { + int16_t bfi; + if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in ISAR_POST_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( numSamplesRead > 0 ) + { + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + ISAR_POST_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = ISAR_POST_REND_FeedInputAudio( hIsarPostRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + if ( splitBinNeedsNewFrame ) + { + if ( ( error = ISAR_POST_REND_FeedSplitBinauralBitstream( hIsarPostRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + + if ( ( error = ISAR_POST_REND_GetSplitBinauralSamples( hIsarPostRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t num_out_channels; + num_out_channels = outBuffer.config.numChannels; + + /* Convert from float to int and from packed to interleaved. + * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ + convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); + + if ( delayNumSamples == -1 ) + { + if ( args.delayCompensationEnabled ) + { + if ( ISAR_POST_REND_GetDelay( hIsarPostRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( hSplitRendFileReadWrite != NULL ) + { + uint32_t pre_rend_delay_ns; + split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns ); + delayNumSamples += (int16_t) roundf( (float) pre_rend_delay_ns * delayTimeScale / 1000000000.f ); + } + + delayNumSamples_orig = delayNumSamples; + } + else + { + delayNumSamples = 0; + } + zeroPad = delayNumSamples; + } + + if ( audioWriter != NULL ) + { + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } + } + + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + + frame++; + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); + } + +#ifdef WMOPS + update_mem(); + update_wmops(); +#endif + } + + /* add zeros at the end to have equal length of synthesized signals */ + if ( audioWriter != NULL ) + { + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + zeroPadToWrite = 0; + } + + if ( !args.quietModeEnabled && args.delayCompensationEnabled ) + { + fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); + } + + fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame ); + +#ifdef DEBUGGING + int32_t cnt_frames_limited, noClipping; + if ( ( cnt_frames_limited = ISAR_POST_REND_GetCntFramesLimited( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited ); + } + if ( ( noClipping = ISAR_POST_REND_GetNoCLipping( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping ); + } +#endif + + /*------------------------------------------------------------------------------------------* + * Close files and deallocate resources + *------------------------------------------------------------------------------------------*/ + + free( inpInt16Buffer ); + free( inFloatBuffer ); + free( outInt16Buffer ); + free( outFloatBuffer ); + + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } + + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); + + AudioFileReader_close( &audioReader ); + AudioFileWriter_close( &audioWriter ); + RotationFileReader_close( &headRotReader ); + RotationFileReader_close( &externalOrientationFileReader ); + + ISAR_POST_REND_Close( &hIsarPostRend ); + +#ifdef DEBUGGING + dbgclose(); +#endif +#ifdef WMOPS + print_wmops(); + print_mem( NULL ); +#endif + + return 0; +} + + +#undef WMC_TOOL_SKIP diff --git a/apps/renderer.c b/apps/renderer.c index 8a9e0b48f84f0745af9cdf84ecc08a362669c8fc..cf97acf947dccd8a056e9ee66e64132628702abd 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -45,10 +45,9 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "aeid_file_reader.h" #include "split_render_file_read_write.h" #include "split_rend_bfi_file_reader.h" -#endif #include "vector3_pair_file_reader.h" #ifdef DEBUGGING #include "debug.h" @@ -66,10 +65,6 @@ #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define SPLIT_REND_BITS_BUFF_SIZE ( ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) + IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) -#endif - #define IVAS_MAX16B_FLT 32767.0f #define IVAS_MIN16B_FLT ( -32768.0f ) @@ -138,10 +133,6 @@ typedef struct IVAS_CUSTOM_LS_DATA inSetupCustom; RendererInput masaBuses[RENDERER_MAX_MASA_INPUTS]; uint16_t numMasaBuses; -#ifdef SPLIT_REND_WITH_HEAD_ROT - RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; - uint16_t numBinBuses; -#endif } InputConfig; typedef struct @@ -150,6 +141,15 @@ typedef struct IVAS_CUSTOM_LS_DATA outSetupCustom; } OutputConfig; +typedef struct +{ + uint16_t *pID; + uint16_t *pValidity; + uint16_t count; + uint16_t selected; + uint16_t frameCounter; +} AcousticEnvironmentSequence; + typedef struct { char executableName[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -160,13 +160,9 @@ typedef struct OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; int16_t numInMetadataFiles; -#ifdef SPLIT_REND_WITH_HEAD_ROT char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; -#endif char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; -#ifdef SPLIT_REND_WITH_HEAD_ROT char splitRendBFIFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; -#endif char referenceVectorFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char referenceRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -189,7 +185,7 @@ typedef struct float syncMdDelay; IVAS_RENDER_FRAMESIZE render_framesize; uint16_t directivityPatternId[RENDERER_MAX_ISM_INPUTS]; - uint16_t acousticEnvironmentId; + AcousticEnvironmentSequence aeSequence; } CmdlnArgs; typedef enum @@ -213,10 +209,8 @@ typedef enum CmdLnOptionId_inputMetadata, CmdLnOptionId_listFormats, CmdLnOptionId_inputGain, -#ifdef SPLIT_REND_WITH_HEAD_ROT CmdLnOptionId_outputMetadata, CmdLnOptionId_SplitRendBFIFile, -#endif CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, CmdLnOptionId_framing, @@ -242,11 +236,7 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_inputMetadata, .match = "input_metadata", .matchShort = "im", -#ifdef SPLIT_REND_WITH_HEAD_ROT .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode", -#else - .description = "Space-separated list of path to metadata files for ISM or MASA inputs", -#endif }, { .id = CmdLnOptionId_outputFile, @@ -272,7 +262,6 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "T", .description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)", }, -#ifdef SPLIT_REND_WITH_HEAD_ROT { .id = CmdLnOptionId_outputMetadata, .match = "output_metadata", @@ -285,7 +274,6 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "prbfi", .description = "Split rendering option: bfi file", }, -#endif { .id = CmdLnOptionId_refRotFile, .match = "reference_rotation_file", @@ -322,10 +310,12 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "lp", .description = "Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees.\nIf specified, overrides the default behavior which attempts to map input to output LFE channel(s)", }, - { .id = CmdlnOptionId_lfeMatrix, - .match = "lfe_matrix", - .matchShort = "lm", - .description = "LFE panning matrix. File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). \nIf specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s)" }, + { + .id = CmdlnOptionId_lfeMatrix, + .match = "lfe_matrix", + .matchShort = "lm", + .description = "LFE panning matrix. File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). \nIf specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s)", + }, { .id = CmdLnOptionId_noDelayCmp, .match = "no_delay_compensation", @@ -390,7 +380,7 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_acousticEnvironmentId, .match = "acoustic_environment_id", .matchShort = "aeid", - .description = "Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration", + .description = "Acoustic environment ID (number > 0) alternatively, it can be a text file where each line contains \"ID duration\" for BINAURAL_ROOM_REVERB output configuration.", }, }; @@ -443,15 +433,9 @@ static void printSupportedAudioConfigs( void ); static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); -#ifdef SPLIT_REND_WITH_HEAD_ROT static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna ); static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn ); -#else -static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer ); - -static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); -#endif /*------------------------------------------------------------------------------------------* @@ -478,13 +462,7 @@ static int16_t getTotalNumInChannels( IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS], -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS], - IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] -#else - IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] -#endif -) + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] ) { int16_t totalNumInChannels = 0; int16_t i, numInputChannels; @@ -561,24 +539,6 @@ static int16_t getTotalNumInChannels( totalNumInChannels += numInputChannels; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - if ( splitBinIds[i] == 0 ) - { - /* Skip inactive inputs */ - continue; - } - - if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - totalNumInChannels += numInputChannels; - } -#endif - return totalNumInChannels; } @@ -587,13 +547,7 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, -#ifdef SPLIT_REND_WITH_HEAD_ROT - MasaFileReader **masaReaders, - SplitFileReadWrite **hhSplitRendFileReadWrite -#else - MasaFileReader **masaReaders -#endif -) + MasaFileReader **masaReaders ) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -640,22 +594,6 @@ static void setupWithSingleFormatInput( } } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - else if ( args.inConfig.numBinBuses != 0 ) - { - *hhSplitRendFileReadWrite = NULL; - if ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - ivas_error error; - error = split_rend_reader_open( hhSplitRendFileReadWrite, args.inMetadataFilePaths[0] ); - if ( error != IVAS_ERR_OK ) - { - fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); - exit( -1 ); - } - } - } -#endif return; } @@ -668,15 +606,14 @@ static float dBToLin( } -#ifdef SPLIT_REND_WITH_HEAD_ROT static int16_t get_cldfb_in_flag( const IVAS_AUDIO_CONFIG audioConfig, - IVAS_RENDER_CONFIG_DATA *renderConfig ) + const IVAS_RENDER_CONFIG_DATA *renderConfig ) { int16_t cldfb_in_flag; cldfb_in_flag = 0; - if ( renderConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( renderConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { #ifdef DEBUGGING cldfb_in_flag = 1; @@ -691,20 +628,6 @@ static int16_t get_cldfb_in_flag( } -static int16_t is_split_post_rend_mode( - CmdlnArgs *args ) -{ - int16_t flag; - - flag = 0; - if ( args->inConfig.numBinBuses > 0 && ( args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - flag = 1; - } - - return flag; -} - static int16_t is_split_pre_rend_mode( CmdlnArgs *args ) { @@ -718,7 +641,6 @@ static int16_t is_split_pre_rend_mode( return flag; } -#endif /*------------------------------------------------------------------------------------------* @@ -735,12 +657,10 @@ int main( RotFileReader *headRotReader = NULL; RotFileReader *externalOrientationFileReader = NULL; RotFileReader *referenceRotReader = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS]; IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_INPUT_CHANNELS]; int16_t cldfb_in_flag, CLDFBframeSize_smpls; SplitRendBFIFileReader *splitRendBFIReader = NULL; -#endif Vector3PairFileReader *referenceVectorReader = NULL; hrtfFileReader *hrtfFileReader = NULL; IVAS_DEC_HRTF_CREND_HANDLE *hSetOfHRTF = NULL; @@ -759,24 +679,18 @@ int main( AudioFileWriter *audioWriter; int32_t inBufferSize; int32_t outBufferSize; -#ifdef SPLIT_REND_WITH_HEAD_ROT int32_t bitsBufferSize; -#endif int16_t *inpInt16Buffer; float *inFloatBuffer; int16_t *outInt16Buffer; float *outFloatBuffer; -#ifdef SPLIT_REND_WITH_HEAD_ROT uint8_t *bitsBufferData = NULL; -#endif IVAS_REND_AudioBuffer inBuffer; IVAS_REND_AudioBuffer outBuffer; -#ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_REND_BitstreamBuffer bitsBuffer; SplitFileReadWrite *hSplitRendFileReadWrite; int16_t delayNumSamples_temp; int32_t delayTimeScale_temp; -#endif int16_t numSamplesRead; int16_t delayNumSamples = -1; int16_t delayNumSamples_orig = 0; @@ -784,8 +698,9 @@ int main( int16_t zeroPadToWrite = 0; int32_t delayTimeScale = 0; int16_t i, numChannels; + IVAS_RENDER_CONFIG_DATA renderConfig; + uint16_t aeID; ivas_error error = IVAS_ERR_OK; - bool splitBinNeedsNewFrame = true; #ifdef WMOPS reset_wmops(); @@ -798,11 +713,19 @@ int main( hMasaMetadata[i] = NULL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT hSplitRendFileReadWrite = NULL; CLDFBframeSize_smpls = 0; cldfb_in_flag = 0; -#endif + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plus_highres = 0; + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { lfeRoutingConfigs[i] = NULL; @@ -859,13 +782,12 @@ int main( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( !isEmptyString( args.splitRendBFIFilePath ) ) { convert_backslash( args.splitRendBFIFilePath ); SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); } -#endif + if ( !isEmptyString( args.externalOrientationFilePath ) ) { if ( RotationFileReader_open( args.externalOrientationFilePath, &externalOrientationFileReader ) != IVAS_ERR_OK ) @@ -894,11 +816,7 @@ int main( else { /* With single-format input, all information is given on command line. */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders, &hSplitRendFileReadWrite ); -#else setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); -#endif } /* Check that there is allowed configuration for MASA format output */ @@ -919,44 +837,14 @@ int main( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*if split renderer is running in post renderer mode*/ - if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) { - error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath ); - if ( error != IVAS_ERR_OK ) - { - fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); - exit( -1 ); - } - audioReader = NULL; - } - else - { -#endif - if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error opening file: %s\n", audioFilePath ); - exit( -1 ); - } -#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); } -#endif int32_t inFileSampleRate = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( audioReader != NULL ) - { -#endif - error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - } - else - { - inFileSampleRate = args.sampleRate; - } -#endif - + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); switch ( error ) { case IVAS_ERR_OK: @@ -985,19 +873,13 @@ int main( } int16_t inFileNumChannels = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( audioReader != NULL ) + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) { -#endif - error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); - if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } -#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); } -#endif + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, !isEmptyString( args.customHrtfFilePath ), args.nonDiegeticPan, args.nonDiegeticPanGain, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) @@ -1124,31 +1006,17 @@ int main( if ( args.renderConfigFilePath[0] != '\0' ) { - IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && !is_split_pre_rend_mode( &args ) ) { fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split pre-rendering mode is enabled. Exiting. \n" ); exit( -1 ); } -#else - if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) - { - fprintf( stderr, "\nExternal Renderer Config is only supported for binaural output configurations. Exiting. \n" ); - exit( -1 ); - } -#endif - if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", ivas_error_to_string( error ) ); -#else - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); -#endif exit( -1 ); } @@ -1160,7 +1028,8 @@ int main( if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, args.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) + aeID = args.aeSequence.count > 0 ? args.aeSequence.pID[0] : 65535; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -1170,29 +1039,24 @@ int main( } else { - fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", args.acousticEnvironmentId ); + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); exit( -1 ); } renderConfig.roomAcoustics.override = 1; } + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) args.render_framesize /* given in number of 5ms subframes */ * 5; + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n", ivas_error_to_string( error ) ); -#else - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); -#endif exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( !is_split_post_rend_mode( &args ) ) - { - CLDFBframeSize_smpls = frameSize_smpls * 2; - cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); - } -#endif + CLDFBframeSize_smpls = frameSize_smpls * 2; + cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); } if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK ) @@ -1254,9 +1118,6 @@ int main( IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS]; IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS]; IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; -#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) { @@ -1274,12 +1135,6 @@ int main( { masaIds[i] = 0u; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) - { - splitBinIds[i] = 0u; - } -#endif for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { @@ -1397,23 +1252,6 @@ int main( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < args.inConfig.numBinBuses; ++i ) - { - if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_SetInputGain( hIvasRend, splitBinIds[i], args.inputGainGlobal * dBToLin( args.inConfig.binBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } -#endif - for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) @@ -1429,11 +1267,7 @@ int main( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds, splitBinIds ); -#else const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); -#endif if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) { @@ -1456,7 +1290,6 @@ int main( exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { if ( ( error = IVAS_REND_openCldfb( cldfbAna, cldfbSyn, totalNumInChannels, numOutChannels, args.sampleRate ) ) != IVAS_ERR_OK ) @@ -1468,13 +1301,19 @@ int main( if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { + if ( ( error = IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, &bitsBuffer.config.codec_frame_size_ms, &bitsBuffer.config.isar_frame_size_ms ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_REND_GetSplitRendBitstreamHeader()!\n" ); + exit( -1 ); + } + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, bitsBuffer.config.codec_frame_size_ms, bitsBuffer.config.isar_frame_size_ms, args.sampleRate, bitsBuffer.config.lc3plus_highres ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); exit( -1 ); @@ -1485,34 +1324,36 @@ int main( { if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { + if ( ( error = IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, &bitsBuffer.config.codec_frame_size_ms, &bitsBuffer.config.isar_frame_size_ms ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_REND_GetSplitRendBitstreamHeader()!\n" ); + exit( -1 ); + } + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp, bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, bitsBuffer.config.codec_frame_size_ms, bitsBuffer.config.isar_frame_size_ms, args.sampleRate, bitsBuffer.config.lc3plus_highres ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); exit( -1 ); } } -#endif if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag == 0 ) { inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); @@ -1539,7 +1380,7 @@ int main( memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); - if ( is_split_pre_rend_mode( &args ) || is_split_post_rend_mode( &args ) ) + if ( is_split_pre_rend_mode( &args ) ) { bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; } @@ -1561,22 +1402,6 @@ int main( bitsBuffer.config.bitsRead = 0; bitsBuffer.config.bitsWritten = 0; bitsBuffer.config.bufLenInBytes = bitsBufferSize; - bitsBuffer.config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - bitsBuffer.config.poseCorrection = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - bitsBuffer.config.codec_frame_size_ms = 20; -#else - inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); - outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); - outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); - - inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; - inBuffer.config.numChannels = (int16_t) totalNumInChannels; - inBuffer.data = inFloatBuffer; - - outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; - outBuffer.config.numChannels = (int16_t) numOutChannels; - outBuffer.data = outFloatBuffer; -#endif #ifdef WMOPS reset_stack(); @@ -1601,54 +1426,53 @@ int main( num_in_channels = inBuffer.config.numChannels; const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT - numSamplesRead = 0; - if ( ( hSplitRendFileReadWrite != NULL ) && is_split_post_rend_mode( &args ) && splitBinNeedsNewFrame ) + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && renderConfigReader != NULL && + args.aeSequence.count > 0 && args.aeSequence.pValidity[args.aeSequence.selected] != 0 ) { - ivas_error error_tmp; - numSamplesRead = (int16_t) inBufferSize; - error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, - &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, - &bitsBuffer.config.codec_frame_size_ms ); - if ( error_tmp != IVAS_ERR_OK ) + if ( ++args.aeSequence.frameCounter >= args.aeSequence.pValidity[args.aeSequence.selected] ) { - if ( error_tmp == IVAS_ERR_END_OF_FILE ) + if ( ++args.aeSequence.selected >= args.aeSequence.count ) { - numSamplesRead = 0; + args.aeSequence.selected = 0; + } + args.aeSequence.frameCounter = 0; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, args.aeSequence.pID[args.aeSequence.selected], &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) + { + if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Invalid acoustic environment configuration parameters\n\n" ); + goto cleanup; + } } else { - fprintf( stderr, "\nUnable to read from bitstream file!\n" ); - exit( -1 ); + fprintf( stderr, "Failed to get acoustic environment with ID %d\n\n", args.aeSequence.pID[args.aeSequence.selected] ); + goto cleanup; + } + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n\n", ivas_error_to_string( error ) ); + goto cleanup; } } } - if ( audioReader != NULL ) + numSamplesRead = 0; + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) { -#endif - /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); - exit( -1 ); - } -#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); } -#endif - if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + if ( numSamplesRead == 0 ) { /* end of input data */ break; } /* Convert from int to float and from interleaved to packed */ -#ifdef SPLIT_REND_WITH_HEAD_ROT convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer, inBuffer.config.is_cldfb, cldfbAna ); -#else - convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); -#endif int16_t num_subframes, sf_idx; num_subframes = (int16_t) args.render_framesize; @@ -1706,11 +1530,7 @@ int main( exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, sf_idx ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1726,25 +1546,6 @@ int main( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /* Read from split renderer bfi file if specified */ - if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) - { - int16_t bfi; - if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_SetSplitRendBFI( hIvasRend, bfi ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in IVAS_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } -#endif - /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) { @@ -1885,87 +1686,33 @@ int main( } } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < args.inConfig.numBinBuses; ++i ) - { - if ( numSamplesRead > 0 ) - { - if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); - - if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - if ( splitBinNeedsNewFrame ) - { - if ( ( error = IVAS_REND_FeedSplitBinauralBitstream( hIvasRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - } -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( args.inConfig.numBinBuses != 0 ) - { - if ( ( error = IVAS_REND_GetSplitBinauralSamples( hIvasRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - else if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = IVAS_REND_GetSplitBinauralBitstream( hIvasRend, outBuffer, &bitsBuffer ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + fprintf( stderr, "Error in IVAS_REND_GetSplitBinauralBitstream(): %s\n", ivas_error_to_string( error ) ); exit( -1 ); } } else { -#endif if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT - fprintf( stderr, "Error %s\n", ivas_error_to_string( error ) ); -#else - fprintf( stderr, "Error in getting samples\n" ); -#endif + fprintf( stderr, "Error in IVAS_REND_GetSamples()%s\n", ivas_error_to_string( error ) ); exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif int16_t num_out_channels; num_out_channels = outBuffer.config.numChannels; /* Convert from float to int and from packed to interleaved. * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ -#ifdef SPLIT_REND_WITH_HEAD_ROT convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, cldfb_in_flag, cldfbSyn ); -#else - convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); -#endif if ( delayNumSamples == -1 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( args.delayCompensationEnabled && !is_split_pre_rend_mode( &args ) ) -#else - if ( args.delayCompensationEnabled ) -#endif { if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) { @@ -1973,15 +1720,6 @@ int main( exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( is_split_post_rend_mode( &args ) && ( hSplitRendFileReadWrite != NULL ) ) - { - uint32_t pre_rend_delay_ns; - split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns ); - delayNumSamples += (int16_t) roundf( (float) pre_rend_delay_ns * delayTimeScale / 1000000000.f ); - } -#endif - delayNumSamples_orig = delayNumSamples; } else @@ -1991,12 +1729,10 @@ int main( zeroPad = delayNumSamples; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( is_split_pre_rend_mode( &args ) ) { - if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, - bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, - bitsBuffer.config.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, + &bitsBuffer.config.bitsWritten ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); exit( -1 ); @@ -2005,7 +1741,6 @@ int main( if ( audioWriter != NULL ) { -#endif if ( delayNumSamples * num_out_channels < outBufferSize ) { if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) @@ -2019,12 +1754,10 @@ int main( { delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT } bitsBuffer.config.bitsRead = 0; bitsBuffer.config.bitsWritten = 0; -#endif /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA2 ) @@ -2129,10 +1862,8 @@ int main( } /* add zeros at the end to have equal length of synthesized signals */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( audioWriter != NULL ) { -#endif for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) { memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); @@ -2150,10 +1881,7 @@ int main( exit( -1 ); } zeroPadToWrite = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif - if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { @@ -2187,18 +1915,21 @@ int main( cleanup: -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( bitsBufferData != NULL ) { free( bitsBufferData ); } -#endif + + if ( args.aeSequence.count > 0 ) + { + free( args.aeSequence.pID ); + free( args.aeSequence.pValidity ); + } for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { IVAS_REND_closeCldfb( cldfbAna, cldfbSyn ); @@ -2206,7 +1937,6 @@ cleanup: split_rend_reader_writer_close( &hSplitRendFileReadWrite ); SplitRendBFIFileReader_close( &splitRendBFIReader ); -#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { @@ -2285,9 +2015,6 @@ static bool parseInConfig( inConfig->numAmbisonicsBuses = 0; inConfig->numMultiChannelBuses = 0; inConfig->numMasaBuses = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT - inConfig->numBinBuses = 0; -#endif /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); @@ -2325,15 +2052,6 @@ static bool parseInConfig( inConfig->ambisonicsBuses[0].inputChannelIndex = 0; inConfig->ambisonicsBuses[0].gain_dB = 0.0f; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: - case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: - inConfig->numBinBuses = 1; - inConfig->binBuses[0].audioConfig = audioConfig; - inConfig->binBuses[0].inputChannelIndex = 0; - inConfig->binBuses[0].gain_dB = 0.0f; - break; -#endif case IVAS_AUDIO_CONFIG_MASA1: case IVAS_AUDIO_CONFIG_MASA2: inConfig->numMasaBuses = 1; @@ -2524,13 +2242,8 @@ static bool parseOrientationTracking( static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ) { -#ifndef SPLIT_REND_WITH_HEAD_ROT - char charBuf[21]; - charBuf[20] = '\0'; -#else char charBuf[25]; charBuf[24] = '\0'; -#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; @@ -2605,7 +2318,6 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) { return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; @@ -2614,7 +2326,6 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; } -#endif if ( strcmp( charBuf, "BINAURAL_ROOM_IR" ) == 0 ) { return IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -2673,6 +2384,50 @@ static bool parseLfePositionConfig( } +static bool parseAcousticEnvironmentIds( + const char *value, + AcousticEnvironmentSequence *aeSequence ) +{ + char config_string[RENDERER_MAX_METADATA_LINE_LENGTH]; + + strncpy( config_string, value, RENDERER_MAX_METADATA_LINE_LENGTH ); + + if ( !is_digits_only( config_string ) ) + { + aeidFileReader *aeidReader = NULL; + + if ( aeidFileReader_open( config_string, &aeidReader ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open aeid file %s \n", config_string ); + return false; + } + + if ( aeidFileReading( aeidReader, &aeSequence->count, &aeSequence->pID, &aeSequence->pValidity ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError while reading aeid from %s\n", config_string ); + return false; + } + + aeidFileReader_close( &aeidReader ); + } + else + { + /* A single acoustic environment */ + if ( NULL == ( aeSequence->pID = malloc( sizeof( uint16_t ) ) ) || + NULL == ( aeSequence->pValidity = malloc( sizeof( uint16_t ) ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", config_string ); + return false; + } + aeSequence->count = 1; + aeSequence->pID[0] = (int16_t) atoi( config_string ); + aeSequence->pValidity[0] = 0; + } + + return true; +} + + static bool checkRequiredArgs( CmdlnArgs args ) { @@ -2687,18 +2442,10 @@ static bool checkRequiredArgs( missingRequiredArg = true; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || - args.inConfig.numAmbisonicsBuses != 0 || - args.inConfig.numMultiChannelBuses != 0 || - args.inConfig.numMasaBuses != 0 || - args.inConfig.numBinBuses != 0; -#else const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || args.inConfig.numAmbisonicsBuses != 0 || args.inConfig.numMultiChannelBuses != 0 || args.inConfig.numMasaBuses != 0; -#endif if ( !args.sceneDescriptionInput && !singleInputSpecified ) { @@ -2755,10 +2502,8 @@ static CmdlnArgs defaultArgs( args.numInMetadataFiles = 0; clearString( args.headRotationFilePath ); -#ifdef SPLIT_REND_WITH_HEAD_ROT clearString( args.outMetadataFilePath ); clearString( args.splitRendBFIFilePath ); -#endif clearString( args.referenceVectorFilePath ); clearString( args.referenceRotationFilePath ); clearString( args.customHrtfFilePath ); @@ -2789,7 +2534,11 @@ static CmdlnArgs defaultArgs( args.directivityPatternId[i] = 65535; } - args.acousticEnvironmentId = 65535; + args.aeSequence.count = 0; + args.aeSequence.pID = NULL; + args.aeSequence.pValidity = NULL; + args.aeSequence.selected = 0; + args.aeSequence.frameCounter = 0; return args; } @@ -2851,7 +2600,6 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; -#ifdef SPLIT_REND_WITH_HEAD_ROT case CmdLnOptionId_outputMetadata: assert( numOptionValues == 1 ); strncpy( args->outMetadataFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -2860,7 +2608,6 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->splitRendBFIFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; -#endif case CmdLnOptionId_referenceVectorFile: assert( numOptionValues == 1 ); strncpy( args->referenceVectorFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -2961,12 +2708,10 @@ static void parseOption( break; case CmdLnOptionId_acousticEnvironmentId: assert( numOptionValues == 1 ); - if ( !is_digits_only( optionValues[0] ) ) + if ( !parseAcousticEnvironmentIds( optionValues[0], &args->aeSequence ) ) { - fprintf( stderr, "Invalid acousting environment ID specified: %s\n", optionValues[0] ); - exit( -1 ); + fprintf( stderr, "Invalid acoustic environment ID specified: %s\n", optionValues[0] ); } - args->acousticEnvironmentId = (int16_t) strtol( optionValues[0], NULL, 10 ); break; case CmdLnOptionId_syncMdDelay: assert( numOptionValues == 1 ); @@ -3863,10 +3608,8 @@ static void printSupportedAudioConfigs( void ) "ISMx (input only)", "MASAx", "BINAURAL (output only)", -#ifdef SPLIT_REND_WITH_HEAD_ROT "BINAURAL_SPLIT_PCM", "BINAURAL_SPLIT_CODED", -#endif "BINAURAL_ROOM_IR (output only)", "BINAURAL_ROOM_REVERB (output only)", }; @@ -3963,20 +3706,14 @@ static void convertInputBuffer( const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, -#ifdef SPLIT_REND_WITH_HEAD_ROT float *floatBuffer, const int16_t cldfb_in_flag, - IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna -#else - float *floatBuffer -#endif -) + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna ) { int16_t chnl, smpl, i; i = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { int16_t slotIdx, numCldfbBands, numFloatPcmSamples; @@ -4017,7 +3754,6 @@ static void convertInputBuffer( } else { -#endif for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) { for ( chnl = 0; chnl < numChannels; ++chnl ) @@ -4034,9 +3770,7 @@ static void convertInputBuffer( ++i; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif return; } @@ -4052,21 +3786,15 @@ static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t *intBuffer, const int16_t cldfb_in_flag, - IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn -#else - int16_t *intBuffer -#endif -) + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn ) { int16_t chnl, smpl, i; float temp; i = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { int16_t slotIdx, numCldfbBands, numPcmSamples, b; @@ -4115,7 +3843,6 @@ static void convertOutputBuffer( } else { -#endif for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) { for ( chnl = 0; chnl < numChannels; ++chnl ) @@ -4135,9 +3862,7 @@ static void convertOutputBuffer( ++i; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif return; } diff --git a/ci/basop-pages/basop_index.html b/ci/basop-pages/basop_index.html new file mode 100644 index 0000000000000000000000000000000000000000..8688232fe49e0da273958c53986e9d3bcdafc2c2 --- /dev/null +++ b/ci/basop-pages/basop_index.html @@ -0,0 +1,16 @@ + + + + + +

Ivas BASOP code Development

+ +

Daily long testvector tests

+ + + + diff --git a/ci/basop-pages/create_report_pages.py b/ci/basop-pages/create_report_pages.py new file mode 100644 index 0000000000000000000000000000000000000000..e3557e252ba32c9b33962f0f7cad677d05d1624d --- /dev/null +++ b/ci/basop-pages/create_report_pages.py @@ -0,0 +1,293 @@ +import csv +import pathlib +import argparse +from functools import partial + + +CSV_DELIM = ";" +SUBPAGE_TMPL_CSS = """ + +""" + +SUBPAGE_TMPL_HTML = """ + +

Report for job {job_name}

+
  • Current run - id: {id_current}
  • +
  • Previous run - id: {id_previous}
  • +
  • Merged csv data
  • + + +
    +How is the table sorted? +
      +
    • Cases with result ERROR or invalid/missing values for the numerical measures are given first
    • +
    • Next are all cases with MLD(current) != MLD(previous), sorted in descending order (biggest MLD increase comes first)
    • +
    • All cases with no difference in MLD are at the bottom
    • +
    +
    +What do the colours indicate +
      +
    • + Red background: +
        +
      • This testcases either triggered an ERROR in the pytest run (probably a crash in the codec) or did not give valid values for the numerical measures (probably an error in the scripts).
      • +
      • For this testcase the MLD increased wrt the previous run - MLD(current) > MLD(previous)
      • +
      +
    • +
    • + Green background: +
        +
      • For this testcase the MLD decreased wrt the previous run - MLD(current) < MLD(previous)
      • +
      +
    • +
    +
    +How to interpret the Result column? +
      +
    • ERROR: An error occured during test run. It should be checked if a crash in the codec occured.
    • +
    • FAIL: An MLD value > 0 was reported. This is to be expected, the test just reports a failure due to how the tests are currently implemented.
    • +
    • PASS: MLD value of 0 was reported. This should only be the case for some special operating points and could indicate that parts of the codec are not (fully) converted yet.
    • +
    + + + + + {table_header_a} + + + {table_header_b} + + +{table_body} + +
    +""" +TD_TMPL_NORMAL = "{}" +TD_TMPL_INCREASE = "{}" +TD_TMPL_REDUCE = "{}" +TR_TMPL = "{}" +TH_TMPL_GLOBAL = '{}' +TH_TMPL_DIFFERENTIAL = '{}' +TH_TMPL_SECOND_ROW = '{}' + +ARROW_UP = '' +ARROW_DOWN = '' + +# expected columns. actual columns are filtered from the incoming data later, this +# is mainly for controlling the order in the output table +COLUMNS = ["testcase", "Result", "MLD", "MAXIMUM ABS DIFF"] +COLUMNS_GLOBAL = COLUMNS[:1] +COLUMNS_DIFFERENTIAL = COLUMNS[1:] +COLUMNS_DIFFERENTIAL_NOT_MLD = COLUMNS_DIFFERENTIAL[2:] + +def create_subpage( + html_out, + csv_out, + csv_current: str, + csv_previous: str, + id_current: int, + id_previous: int, + job_name: str, +): + merged_reports = merge_and_cleanup_mld_reports( + csv_current, csv_previous, id_current, id_previous + ) + write_out_csv(merged_reports, merged_reports[0].keys(), csv_out) + + table_header_a = "".join([TH_TMPL_GLOBAL.format(c) for c in COLUMNS_GLOBAL] + [TH_TMPL_DIFFERENTIAL.format(c) for c in COLUMNS_DIFFERENTIAL]) + table_header_b = list() + for c in COLUMNS_DIFFERENTIAL: + table_header_b.append(TH_TMPL_SECOND_ROW.format(f"Previous Run
    ID: {id_previous}")) + table_header_b.append(TH_TMPL_SECOND_ROW.format(f"Current Run
    ID: {id_current}")) + table_header_b = "".join(table_header_b) + table_body = "\n".join( + tr_from_row(row, id_current, id_previous) for row in merged_reports + ) + new_subpage = SUBPAGE_TMPL_CSS + SUBPAGE_TMPL_HTML.format( + id_current=id_current, + id_previous=id_previous, + table_body=table_body, + job_name=job_name, + table_header_a=table_header_a, + table_header_b=table_header_b, + ) + with open(html_out, "w") as f: + f.write(new_subpage) + + +def write_out_csv(data, col_names, outfile): + with open(outfile, "w") as f: + writer = csv.DictWriter(f, col_names, delimiter=";") + writer.writeheader() + for row in data: + writer.writerow(row) + + +def tr_from_row(row, id_current, id_previous): + tr = list() + + # pre-filter columns to handle case where new columns are added + # only include columns that are there in both data + columns_global = [c for c in COLUMNS_GLOBAL if c in row] + diff_col_tmpl = "{}-{}" + incoming_cols = row.keys() + columns_differential = [ + c + for c in COLUMNS_DIFFERENTIAL + if diff_col_tmpl.format(c, id_current) in incoming_cols + and diff_col_tmpl.format(c, id_previous) in incoming_cols + ] + + for c in columns_global: + # this is currently for the "testcase" column - here we don't compare, just one value is used + tr.append(TD_TMPL_NORMAL.format(row[c])) + for c in columns_differential: + # this is for all columns where we compare between current and previous run + prev = row[f"{c}-{id_previous}"] + curr = row[f"{c}-{id_current}"] + + if c == "Result": + # print errors in bold red font + td_tmpl = TD_TMPL_INCREASE if prev == "ERROR" else TD_TMPL_NORMAL + tr.append(td_tmpl.format(prev)) + td_tmpl = TD_TMPL_INCREASE if curr == "ERROR" else TD_TMPL_NORMAL + tr.append(td_tmpl.format(curr)) + else: + td_tmpl_curr = TD_TMPL_NORMAL + td_tmpl_prev = TD_TMPL_NORMAL + try: + if float(curr) > float(prev): + curr += f" {ARROW_UP}" + td_tmpl_curr = TD_TMPL_INCREASE + elif float(curr) < float(prev): + curr += f" {ARROW_DOWN}" + td_tmpl_curr = TD_TMPL_REDUCE + except ValueError: + # if we land here, one of the cells is not a number, this indicates a crash + # or some error in the scripts, so mark with red as well + td_tmpl_curr = TD_TMPL_INCREASE + td_tmpl_prev = TD_TMPL_INCREASE + + tr.append(td_tmpl_prev.format(prev)) + tr.append(td_tmpl_curr.format(curr)) + + return TR_TMPL.format("\n".join(tr)) + + +def merge_and_cleanup_mld_reports( + csv_current: str, csv_previous: str, id_current: int, id_previous: int +): + with open(csv_current) as f: + current_reader = csv.DictReader(f, delimiter=CSV_DELIM) + current = list(current_reader) + with open(csv_previous) as f: + previous = list(csv.DictReader(f, delimiter=CSV_DELIM)) + + # TODO: handle newly added testcases - for now assume that both have the same columns + merge_key = "testcase" + other_keys = [k for k in current_reader.fieldnames if k != merge_key] + merged = merge_tables( + current, previous, id_current, id_previous, merge_key, other_keys + ) + + # TODO: sort on result as well + mld_col_curr = f"MLD-{id_current}" + mld_col_prev = f"MLD-{id_previous}" + + def sort_func(x, other_col_pairs): + """ + Sort function for the rows. Puts missing or invalid values on top as those usually + indicate crashes. Then sorts by MLD difference in descending order. MLD diffs of zero + are uninteresting and are put last. + """ + try: + float(x[mld_col_curr]) + float(x[mld_col_prev]) + except ValueError: + # Value is no valid floating point value + return float("inf") + + diff = float(x[mld_col_curr]) - float(x[mld_col_prev]) + + # if no diff in mld col found, check if there is a diff in any other measure + if diff == 0: + diff = float("-inf") + + diff_other = 0 + for col_pair in other_col_pairs: + col_prev = col_pair[0] + col_curr = col_pair[1] + diff_other += abs(float(x[col_curr]) - float(x[col_prev])) + + if diff_other > 0: + diff = -1000000 + + return diff + + other_col_pairs = [(f"{col}-{id_previous}", f"{col}-{id_current}") for col in COLUMNS_DIFFERENTIAL_NOT_MLD] + merged = sorted(merged, key=partial(sort_func, other_col_pairs=other_col_pairs), reverse=True) + + # remove the unecessary whole path from the testcase names + for row in merged: + row["testcase"] = pathlib.Path(row["testcase"]).name + + return merged + + +def merge_tables(tbl1, tbl2, suffix1, suffix2, merge_key, other_keys): + merged = list() + + for row1 in tbl1: + new_row = dict() + for key in other_keys: + new_row[f"{key}-{suffix1}"] = row1[key] + + for row2 in tbl2: + if row1[merge_key] == row2[merge_key]: + new_row[merge_key] = row1[merge_key] + for key in other_keys: + new_row[f"{key}-{suffix2}"] = row2[key] + break + + merged.append(new_row) + + return merged + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("html_out") + parser.add_argument("csv_out") + parser.add_argument("csv_current") + parser.add_argument("csv_previous") + parser.add_argument("id_current", type=int) + parser.add_argument("id_previous", type=int) + parser.add_argument("job_name") + args = parser.parse_args() + + create_subpage( + args.html_out, + args.csv_out, + args.csv_current, + args.csv_previous, + args.id_current, + args.id_previous, + args.job_name, + ) diff --git a/ci/check_self_test_names.py b/ci/check_self_test_names.py new file mode 100644 index 0000000000000000000000000000000000000000..3dea1a1200301d6cfd89c07f4811a901134dd627 --- /dev/null +++ b/ci/check_self_test_names.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +""" + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. +""" +import argparse +import sys + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("prm_file", type=str) + parser.add_argument("max_length", type=int) + args = parser.parse_args() + + skiplines = 8 + exceeded = [] + with open(args.prm_file, "r") as f: + for line in f: + if skiplines > 0: + skiplines = skiplines - 1 + else: + if "//" in line and all(x not in line for x in ["IVAS_cod", "IVAS_dec", "IVAS_rend"]) and len(line) > args.max_length: + exceeded.append(line) + + if exceeded: + print( + f"Failed! *** Following tests cases exceeded the limit of {args.max_length} characters ***\n" + ) + print("\n".join(exceeded)) + sys.exit(-1) + + print("All OK") + sys.exit(0) diff --git a/ci/get_id_of_last_job_occurence.py b/ci/get_id_of_last_job_occurence.py index 449902f50a12919897ef0c0aaac41c197cd59f05..465d4c19a1ce077daed574761214a31740b83588 100755 --- a/ci/get_id_of_last_job_occurence.py +++ b/ci/get_id_of_last_job_occurence.py @@ -1,67 +1,73 @@ #!/usr/bin/env python3 """ - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. +(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. """ import argparse import requests + PER_PAGE_SUFFIX = "?per_page=50" PAGE_SUFFIX = "&page={}" -API_BASE_URL = "https://forge.3gpp.org/rep/api/v4/projects/49" +API_URL_TMPL = "https://forge.3gpp.org/rep/api/v4/projects/{}/pipelines" +SCOPE_FAILED = "&scope[]=failed" +SCOPE_SUCCESS = "&scope[]=success" -def get_job_id(branch_name, job_name): +def get_job_id(branch_name, job_name, project_id, success_only): job_id = -1 # check last 500 pipelines max for page in range(100): - url_pls = API_BASE_URL + "/pipelines" + url_pls = API_URL_TMPL.format(project_id) # need both suffixes here to descend through the pages and get also older pipelines suffix = PER_PAGE_SUFFIX + PAGE_SUFFIX.format(page) resp_pls = requests.get(url_pls + suffix) for pl in resp_pls.json(): if pl["ref"] == branch_name: - url_jobs = url_pls + f"/{pl['id']}/jobs" + url_args = PER_PAGE_SUFFIX + + url_args += SCOPE_SUCCESS + if not success_only: + url_args += SCOPE_FAILED - # only one of the suffixes here - this assumes only max of 50 jobs per pipeline - # so only one page needed - resp_jobs = requests.get(url_jobs + PER_PAGE_SUFFIX) + url_jobs = url_pls + f"/{pl['id']}/jobs" + url_args + resp_jobs = requests.get(url_jobs) if job_name not in resp_jobs.text: continue # find actual job by name for job in resp_jobs.json(): - if job["name"] == job_name and job["status"] == "success": + if job["name"] == job_name: job_id = job["id"] break if job_id >= 0: @@ -75,10 +81,12 @@ def get_job_id(branch_name, job_name): if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument("branch_name") - parser.add_argument("job_name") + parser.add_argument("branch_name", help="Name of the branch to search on") + parser.add_argument("job_name", help="Name of the job to get the id of") + parser.add_argument("project_id", help="ID of project to search in", type=int) + parser.add_argument("--success_only", help="Only include jobs with status 'success'", action="store_true") args = parser.parse_args() - job_id = get_job_id(args.branch_name, args.job_name) + job_id = get_job_id(args.branch_name, args.job_name, args.project_id, args.success_only) print(job_id) diff --git a/ci/remove_unsupported_testcases.py b/ci/remove_unsupported_testcases.py new file mode 100644 index 0000000000000000000000000000000000000000..09ddbc0a019dce056cebaf39210a19fe51b30716 --- /dev/null +++ b/ci/remove_unsupported_testcases.py @@ -0,0 +1,88 @@ +__copyright__ = """ +(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. +""" + +from pathlib import Path +import argparse + +# Enter tag of testcases to remove here WITHOUT the leading // +TESTCASES = [ + "OMASA 2Dir2TC 4ISM at br sw techs 13.2 to 512 kbps start 80 kbps, 48kHz in, 48kHz out, EXT out", + "OSBA planar FOA 2ISM at 512 kbps, 48 kHz in, 48 kHz out, BINAURAL out", + "4 ISM with extended metadata at 128 kbps, 48 kHz in, 48 kHz out, BINAURAL_ROOM_REVERB out, rendconf dir w id", + "OSBA planar FOA 1ISM at 256 kbps, 48 kHz in, 48 kHz out, BINAURAL out", + "Multi-channel 5_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 10%, bandwidth switching", + "OSBA FOA 4ISM at bitrate switching 13.2 to 512 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 5%, bandwidth switching", + "OSBA FOA 2ISM at 64 kbps, 48kHz in, 48kHz out, HOA3 out, bandwidth switching", + "OMASA 2Dir2TC 4ISM at br sw techs 13.2 to 512 kbps start 80 kbps, 48kHz in, 48kHz out, EXT out", + "OSBA planar FOA 2ISM at 512 kbps, 48 kHz in, 48 kHz out, BINAURAL out", + "OSBA planar FOA 1ISM at 256 kbps, 48 kHz in, 48 kHz out, BINAURAL out", + "SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB rendconf sel acoustic env", + "OSBA FOA 4ISM at br sw 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching", + "stereo bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, DTX on, EXT out", + "SBA FOA bitrate switching from 13.2 kbps to 192 kbps, 32kHz in, 32kHz out, DTX on, EXT out", + "SBA 2OA bitrate switching from 13.2 kbps to 128 kbps, 32kHz in, 32kHz out, DTX on, EXT out", + "SBA 3OA bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, DTX on, random FER at 5%, EXT out", + "Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, EXT out", + "Multi-channel 5_1_2 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, EXT out", + "Multi-channel 5_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 32kHz out, EXT out", + "Multi-channel 7_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 16kHz out, EXT out", + "Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, EXT out", +] + + +def remove_testcases(cfg: Path, testcases: list): + """ + Go through file line by line and copy all testcases except the given ones + """ + with open(cfg, "r") as f: + content_in = f.readlines() + + content_out = list() + copy_flag = True + for line in content_in: + if any([tc in line for tc in testcases]): + copy_flag = False + + if copy_flag: + content_out.append(line) + elif line == "\n": + copy_flag = True + + with open(cfg, "w") as f: + f.write("".join(content_out)) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("cfg_files", nargs="+", type=Path) + args = parser.parse_args() + + for f in args.cfg_files: + remove_testcases(f, TESTCASES) diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py index 65c88ee0c0c7f374919c5c5f79de914ee3422f13..eda1fade6c15c29e5793a1e6d7c04050a070a753 100755 --- a/ci/run_scheduled_sanitizer_test.py +++ b/ci/run_scheduled_sanitizer_test.py @@ -58,8 +58,8 @@ N_FRAMES_DLY_PROFILE = 7500 GENPATT_CMD = f"gen-patt -tailstat -fer -g192 -gamma 0 -rate 0.15 -tol 0.001 -reset -n {N_FRAMES_DLY_PROFILE} {EP_FILE}" MC_MODES = ["5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] AMBISONICS_MODES = ["HOA3", "HOA2", "FOA", "PlanarHOA3", "PlanarHOA2", "PlanarFOA"] -# timeout of 15 minutes per en/decoding to safeguard against endless loops -TIMEOUT = 60 * 20 +# timeout of 25 minutes per en/decoding to safeguard against endless loops +TIMEOUT = 60 * 25 HEAD_TRAJ_FILE = str(pathlib.Path("./head_rot_traj.csv").resolve()) EXOF_TRAJ_FILE = str(pathlib.Path("./exof_traj.csv").resolve()) diff --git a/ci/setup_pages.py b/ci/setup_pages.py index 10a2e9e84ecf2f5ad1a351ca2cb040e0f5a1b569..a28c12675e6d223ce6474265c05f2af932879cef 100755 --- a/ci/setup_pages.py +++ b/ci/setup_pages.py @@ -3,10 +3,16 @@ import os import pathlib import subprocess import sys +import shutil +from tempfile import TemporaryDirectory from get_id_of_last_job_occurence import get_job_id -JOBS = [ +PROJECT_ID_FLOAT_REPO = 49 +PROJECT_ID_BASOP_REPO = 77 + + +JOBS_FLOAT_REPO = [ "complexity-stereo-in-stereo-out", "complexity-ism-in-binaural-out", "complexity-sba-hoa3-in-hoa3-out", @@ -15,44 +21,83 @@ JOBS = [ "complexity-StereoDmxEVS-stereo-in-mono-out", "coverage-test-on-main-scheduled", ] +JOBS_BASOP_REPO = [ + "ivas-pytest-mld-long-dec", + "ivas-pytest-mld-long-dec-lev+10", + "ivas-pytest-mld-long-dec-lev-10", +] + +JOBS_FOR_PROJECT_ID = { + PROJECT_ID_FLOAT_REPO: JOBS_FLOAT_REPO, + PROJECT_ID_BASOP_REPO: JOBS_BASOP_REPO, +} + ARTIFACTS = "artifacts.zip" API_URL_BASE = "https://forge.3gpp.org/rep/api/v4/projects/{}/jobs" -PUBLIC = "./public" +PUBLIC_FOLDER = pathlib.Path("./public").absolute() def main(): + PUBLIC_FOLDER.mkdir() - public_folder = pathlib.Path(PUBLIC) - public_folder.mkdir() + project_id = int(os.environ["CI_PROJECT_ID"]) + jobs = JOBS_FOR_PROJECT_ID[project_id] + success_only = project_id == PROJECT_ID_FLOAT_REPO + failed_count = get_artifacts_for_jobs_and_return_num_failed( + jobs, project_id, success_only + ) + if failed_count == len(jobs): + print("Artifact collection failed for all jobs to check.") + sys.exit(1) + + index_html = PUBLIC_FOLDER.joinpath("index.html") + if project_id == PROJECT_ID_FLOAT_REPO: + src = pathlib.Path("ci/index-pages.html").absolute() + shutil.move(src, index_html) + elif project_id == PROJECT_ID_BASOP_REPO: + src = pathlib.Path("ci/basop-pages/basop_index.html").absolute() + shutil.move(src, index_html) + + sys.exit(0) + + +def get_artifacts_for_jobs_and_return_num_failed( + jobs: list, project_id: int, success_only: bool +) -> int: + """ + Get specified artifact folders for all jobs given and put them into the public folder. + + jobs: dictionary with the job names in the keys and a list of the + public folders to copy from the artifacts in the values + if "-public" is in the list, the actual folder name to copy is the key with "-public" appended + """ failed_count = 0 - for job in JOBS: - job_id = get_job_id(os.environ["CI_COMMIT_REF_NAME"], job) + + for job in jobs: + job_id = get_job_id( os.environ["CI_DEFAULT_BRANCH"], job, project_id, success_only) + print(f"{job_id} - {job}") try: - curl_for_artifacts(job_id) + with TemporaryDirectory() as tmp_dir: + curl_for_artifacts(job_id, tmp_dir) - job_public = job + "-public" - if job == "coverage-test-on-main-scheduled": - job_public = "coverage" - pathlib.Path("coverage_stv").rename( - public_folder.joinpath("coverage_stv") - ) + tmp_dir = pathlib.Path(tmp_dir) - pathlib.Path(job_public).rename(public_folder.joinpath(job_public)) + for artifact in tmp_dir.iterdir(): + src = tmp_dir.joinpath(artifact).absolute() + dst = PUBLIC_FOLDER.joinpath(artifact.name) + print(f"{src} -> {dst}") + shutil.move(src, dst) except subprocess.CalledProcessError: print(f"Could not get artifacts for {job}") failed_count += 1 - if failed_count == len(JOBS): - sys.exit(1) - - pathlib.Path("ci/index-pages.html").rename(public_folder.joinpath("index.html")) - sys.exit(0) + return failed_count -def curl_for_artifacts(job_id): +def curl_for_artifacts(job_id: int, exdir: str): cmd = [ "curl", "--request", @@ -61,6 +106,7 @@ def curl_for_artifacts(job_id): "--output", ARTIFACTS, ] + print(cmd) subprocess.run(cmd, check=True) # check for valid archive (if not, it is likely a 404 page, then display that) @@ -73,7 +119,7 @@ def curl_for_artifacts(job_id): raise subprocess.CalledProcessError(-1, "Unzip check failed") # do the actual unzipping - cmd = ["unzip", ARTIFACTS] + cmd = ["unzip", ARTIFACTS, "-d", exdir] subprocess.run(cmd, check=True) diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index 57e3e1b154d7a9d57cacda8956ed84af04e05a3b..071b9a0be620c8ebf8aef7c00f50914459088047 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -52,12 +52,11 @@ fi cfg=./scripts/config/ci_linux.json -dly_profile=./scripts/dly_error_profiles/dly_error_profile_10.dat +dly_profile=./scripts/dly_error_profiles/dly_error_profile_10_smoke_test.dat ism_md_cmd="--ism_metadata_files /usr/local/ltv/ltvISM1.csv /usr/local/ltv/ltvISM2.csv /usr/local/ltv/ltvISM3.csv /usr/local/ltv/ltvISM4.csv" duration_arg="-U 1:2" verbosity_cmd="-z console" timeout_cmd="--timeout 20" -ep_file="ci/complexity_measurements/ep_10pct_fer.g192" if [ $BUILD -eq 1 ];then # Enable memory macros to find unbalanced memory allocations/deallocations @@ -88,33 +87,26 @@ echo "\n======================= 1. non-ism modes no FEC =======================\ ./scripts/runIvasCodec.py $verbosity_cmd -m $non_ism_modes -p $cfg $duration_arg $timeout_cmd | tee smoke_test_output.txt echo "\n======================= 2. ism modes no FEC =======================\n\n" ./scripts/runIvasCodec.py $verbosity_cmd -m $ism_modes -p $cfg $duration_arg $ism_md_cmd $timeout_cmd | tee smoke_test_output.txt -# run the decoding again, but with 15% frame loss -echo "\n======================= 3. all modes with FEC =======================\n\n" -./scripts/runIvasCodec.py $verbosity_cmd -p $cfg $duration_arg -f="$ep_file" --decoder_only $timeout_cmd | tee smoke_test_output_plc.txt - -# run JBM modes - EXT is excluded as not supported yet -formats_with_no_ext_out=$(./scripts/runIvasCodec.py -L | grep -v MASA | grep -v ISM | grep -v OSBA) -formats_with_ext_out=$(./scripts/runIvasCodec.py -L | grep 'MASA\|ISM\|OSBA') -echo "\n======================= 4. JBM, modes with no EXT =======================\n\n" -./scripts/runIvasCodec.py $verbosity_cmd -C $formats_with_no_ext_out -p $cfg $duration_arg --decoder_only --jbm_file $dly_profile $timeout_cmd | tee smoke_test_output_jbm_noEXT.txt -echo "\n======================= 5. JBM, modes with EXT =======================\n\n" -./scripts/runIvasCodec.py $verbosity_cmd -C $formats_with_ext_out -p $cfg $duration_arg --decoder_only --jbm_file $dly_profile --oc BINAURAL BINAURAL_ROOM_IR mono stereo FOA HOA3 5_1 7_1_4 $timeout_cmd | tee -a smoke_test_output_jbm_noEXT.txt + +# all modes with simulated network delay - this includes JBM TSM and lost frames +echo "\n======================= 3. JBM =======================\n\n" +./scripts/runIvasCodec.py $verbosity_cmd -p $cfg $duration_arg --decoder_only --jbm_file $dly_profile $timeout_cmd | tee smoke_test_output_jbm.txt # run all modes with binaural output using external files formats_with_bin_out=$(./scripts/runIvasCodec.py -L | grep -v "mono\|tereo") -bin_out_modes="BINAURAL BINAURAL_ROOM_IR" +bin_out_modes="BINAURAL BINAURAL_ROOM_IR BINAURAL_ROOM_REVERB" -echo "\n======================= 6. binaural out with HRTF files - WB =======================\n\n" +echo "\n======================= 4. binaural out with HRTF files - WB =======================\n\n" wb_modes=$(./scripts/runIvasCodec.py -l -C $formats_with_bin_out | grep _wb_) hrtf_wb="../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin" ./scripts/runIvasCodec.py $verbosity_cmd -p $cfg -m $wb_modes $duration_arg -D="-hrtf ${hrtf_wb}" --decoder_only --oc $bin_out_modes $timeout_cmd | tee -a smoke_test_output_hrtf.txt -echo "\n======================= 7. binaural out with HRTF files - SWB =======================\n\n" +echo "\n======================= 5. binaural out with HRTF files - SWB =======================\n\n" swb_modes=$(./scripts/runIvasCodec.py -l -C $formats_with_bin_out | grep _swb_) hrtf_swb="../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin" ./scripts/runIvasCodec.py $verbosity_cmd -p $cfg -m $swb_modes $duration_arg -D="-hrtf ${hrtf_swb}" --decoder_only --oc $bin_out_modes $timeout_cmd | tee -a smoke_test_output_hrtf.txt -echo "\n======================= 8. binaural out with HRTF files - FB =======================\n\n" +echo "\n======================= 6. binaural out with HRTF files - FB =======================\n\n" fb_modes=$(./scripts/runIvasCodec.py -l -C $formats_with_bin_out | grep _fb_) hrtf_fb="../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin" ./scripts/runIvasCodec.py $verbosity_cmd -p $cfg -m $fb_modes $duration_arg -D="-hrtf ${hrtf_fb}" --decoder_only --oc $bin_out_modes $timeout_cmd | tee -a smoke_test_output_hrtf.txt diff --git a/ci/smoke_test_complexity.sh b/ci/smoke_test_complexity.sh new file mode 100755 index 0000000000000000000000000000000000000000..abd724c88f189e0930a01b1b4e491586e412c3bb --- /dev/null +++ b/ci/smoke_test_complexity.sh @@ -0,0 +1,214 @@ +#! /usr/bin/bash + +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +# contributors to this repository. All Rights Reserved. + +# This software is protected by copyright law and by international treaties. +# The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +# contributors to this repository retain full ownership rights in their respective contributions in +# the software. This notice grants no license of any kind, including but not limited to patent +# license, nor is any license granted by implication, estoppel or otherwise. + +# Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +# contributions. + +# This software is provided "AS IS", without any express or implied warranties. The software is in the +# development stage. It is intended exclusively for experts who have experience with such software and +# solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +# and fitness for a particular purpose are hereby disclaimed and excluded. + +# Any dispute, controversy or claim arising under or in relation to providing this software shall be +# submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +# accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +# the United Nations Convention on Contracts on the International Sales of Goods. + +function usage { + echo + echo "Usage:" + echo " smoke_test_complexity.sh [--max_cores nMaxCores]" + echo + echo " nMaxCores - the number of CPUs to use (default 42)" + exit +} + +if [ ! -d "lib_com" ]; then + echo "not in root directory! - please run in IVAS root" + exit 1 +fi + +if [[ -z "$1" ]]; then + MAX_CORES=42 +elif [[ "$1" == "--max_cores" ]]; then + if [[ -z "$2" ]]; then + echo "Need maximum number of cores" + exit 1 + else + MAX_CORES=$2 + fi +else + usage +fi + +cfg=./scripts/config/ci_linux_ltv.json +ism_md_cmd="--ism_metadata_files /usr/local/ltv/ltvISM1.csv /usr/local/ltv/ltvISM2.csv /usr/local/ltv/ltvISM3.csv /usr/local/ltv/ltvISM4.csv" +duration_arg="" +complexity_cmd="--checks COMPLEXITY --create_complexity_tables" +max_num_workers="--max_workers $MAX_CORES" + +# prepare combined format test signals +echo "\n======================= 0. preparing combined format test inputs =======================\n\n" +./scripts/prepare_combined_format_inputs.py + +# Modes +mono_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^mono) +FOA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^FOA) +HOA2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^HOA2) +HOA3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^HOA3) +PlanarFOA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^PlanarFOA) +PlanarHOA2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^PlanarHOA2) +PlanarHOA3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^PlanarHOA3) +MASA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^MASA) +MC_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^MC) +stereo_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^stereo) +stereoDmx_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^StereoDmx) +OMASA_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OMASA) +OSBA_ISM1_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM1) +OSBA_ISM2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM2) +OSBA_ISM3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM3) +OSBA_ISM4_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^OSBA_ISM4) +ISM1_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM1) +ISM2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM2) +ISM3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM3) +ISM4_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM4) +ISM_plus1_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+1) +ISM_plus2_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+2) +ISM_plus3_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+3) +ISM_plus4_modes=$(./scripts/IvasBuildAndRunChecks.py -l | grep ^ISM+4) + + +echo "\n======================= 1. Mono =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_mono_no_fec -m $mono_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_mono.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 2. FOA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_FOA_no_fec -m $FOA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_FOA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 3. HOA2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_HOA2_no_fec -m $HOA2_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_HOA2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 4. HOA3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_HOA3_no_fec -m $HOA3_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_HOA3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 5. PlanarFOA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_PlanarFOA_no_fec -m $PlanarFOA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_PlanarFOA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 6. PlanarHOA2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_PlanarHOA2_no_fec -m $PlanarHOA2_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_PlanarHOA2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 7. PlanarHOA3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_PlanarHOA3_no_fec -m $PlanarHOA3_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_PlanarHOA3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 8. MASA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_MASA_no_fec -m $MASA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_MASA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 9. MC =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_MC_no_fec -m $MC_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_MC.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 10. stereo =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_stereo_no_fec -m $stereo_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_stereo.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 11. stereoDmx =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_stereoDmx_no_fec -m $stereoDmx_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_stereoDmx.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 12. OMASA =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_OMASA_no_fec -m $OMASA_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OMASA.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 13. OSBA ISM1 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_OSBA_ISM1_no_fec -m $OSBA_ISM1_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM1.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 14. OSBA ISM2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_OSBA_ISM2_no_fec -m $OSBA_ISM2_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 15. OSBA ISM3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_OSBA_ISM3_no_fec -m $OSBA_ISM3_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 16. OSBA ISM4 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_OSBA_ISM4_no_fec -m $OSBA_ISM4_modes -p $cfg $duration_arg $max_num_workers | tee smoke_test_output_OSBA_ISM4.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 15. ISM1 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM1_no_fec -m $ISM1_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM1.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 16. ISM2 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM2_no_fec -m $ISM2_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 17. ISM3 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM3_no_fec -m $ISM3_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 18. ISM4 =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM4_no_fec -m $ISM4_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM4.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 19. ISM1 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM_plus1_no_fec -m $ISM_plus1_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus1.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 20. ISM2 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM_plus2_no_fec -m $ISM_plus2_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus2.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 21. ISM3 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM_plus3_no_fec -m $ISM_plus3_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus3.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ +echo "\n======================= 22. ISM4 + extended metadata =======================\n\n" +./scripts/IvasBuildAndRunChecks.py $complexity_cmd ltv_complexity_ISM_plus4_no_fec -m $ISM_plus4_modes -p $cfg $duration_arg $ism_md_cmd $max_num_workers | tee smoke_test_output_ISM_plus4.txt +rm -r ./COMPLEXITY/dec/ +rm -r ./COMPLEXITY/enc/ +rm -r ./COMPLEXITY/pcm/ diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index cff1f5b5e01ec4571539bf1b77c620395946f4fd..47fbbb9db21b89d728e4224aeb3de71ab332dd42 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -884,7 +884,11 @@ ivas_error check_ind_list_limits( } else { +#ifdef DEBUGGING return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Buffer of indices corrupted in frame %d! Attempt to overwrite indice ID = %d (value: %d, bits: %d)!\n", frame, hBstr->ind_list[hBstr->nb_ind_tot].id, hBstr->ind_list[hBstr->nb_ind_tot].value, hBstr->ind_list[hBstr->nb_ind_tot].nb_bits ); +#else + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Buffer of indices corrupted! Attempt to overwrite indice ID = %d (value: %d, bits: %d)!\n", hBstr->ind_list[hBstr->nb_ind_tot].id, hBstr->ind_list[hBstr->nb_ind_tot].value, hBstr->ind_list[hBstr->nb_ind_tot].nb_bits ); +#endif } } @@ -939,7 +943,11 @@ ivas_error push_indice( /* check the limits of the list of indices */ if ( ( error = check_ind_list_limits( hBstr ) ) != IVAS_ERR_OK ) { +#ifdef DEBUGGING return IVAS_ERROR( error, "Error occured in push_indice() while re-allocating the list of indices (frame %d) !\n", frame ); +#else + return IVAS_ERROR( error, "Error occured in push_indice() while re-allocating the list of indices!\n" ); +#endif } /* find the location in the list of indices based on ID */ @@ -1095,7 +1103,11 @@ ivas_error push_next_bits( /* check the limits of the list of indices */ if ( ( error = check_ind_list_limits( hBstr ) ) != IVAS_ERR_OK ) { +#ifdef DEBUGGING return IVAS_ERROR( error, "Error occured in push_next_bits() while re-allocating the list of indices (frame %d) !\n", frame ); +#else + return IVAS_ERROR( error, "Error occured in push_next_bits() while re-allocating the list of indices!\n" ); +#endif } ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; @@ -1114,7 +1126,11 @@ ivas_error push_next_bits( /* check the limits of the list of indices */ if ( ( error = check_ind_list_limits( hBstr ) ) != IVAS_ERR_OK ) { +#ifdef DEBUGGING return IVAS_ERROR( error, "Error occured in push_next_bits() while re-allocating the list of indices (frame %d) !\n", frame ); +#else + return IVAS_ERROR( error, "Error occured in push_next_bits() while re-allocating the list of indices!\n" ); +#endif } ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index f12eb6940f8bca5271cbdf66baba5d89fccc8c16..279e00b986243a795ce04cdc80cf1f852fdd4601 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -57,6 +57,12 @@ #define IVAS_MAX_PARAM_SPATIAL_SUBFRAMES 4 #define IVAS_ROOM_ABS_COEFF 6 +/* Maximum buffer length (per channel) in samples */ +#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) + +/* Frame size required when rendering to binaural */ +#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 + /*----------------------------------------------------------------------------------* * Common API enum for output audio configurations *----------------------------------------------------------------------------------*/ @@ -196,14 +202,14 @@ typedef struct _IVAS_JBM_TRACE_DATA } IVAS_JBM_TRACE_DATA; -#ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------------------------* * Split rendering API constants, structures, and enums *----------------------------------------------------------------------------------*/ -#define IVAS_MAX_SPLIT_REND_BITRATE 768000 -#define IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) -#define IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define ISAR_MAX_SPLIT_REND_BITRATE 768000 +#define ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) ISAR_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) +#define ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define SPLIT_REND_BITS_BUFF_SIZE ( ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES + ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) typedef enum { @@ -215,47 +221,49 @@ typedef enum YAW_ROLL, PITCH_ROLL -} IVAS_SPLIT_REND_ROT_AXIS; +} ISAR_SPLIT_REND_ROT_AXIS; typedef enum { - IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, -} IVAS_SPLIT_REND_POSE_CORRECTION_MODE; +} ISAR_SPLIT_REND_POSE_CORRECTION_MODE; typedef enum { - IVAS_SPLIT_REND_CODEC_LCLD, - IVAS_SPLIT_REND_CODEC_LC3PLUS, - IVAS_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ - IVAS_SPLIT_REND_CODEC_NONE + ISAR_SPLIT_REND_CODEC_LCLD, + ISAR_SPLIT_REND_CODEC_LC3PLUS, + ISAR_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ + ISAR_SPLIT_REND_CODEC_NONE -} IVAS_SPLIT_REND_CODEC; +} ISAR_SPLIT_REND_CODEC; typedef enum { - IVAS_SPLIT_REND_RENDERER_SELECTION_CREND, - IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV, - IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, - IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND, - IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT, + ISAR_SPLIT_REND_RENDERER_SELECTION_CREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV, + ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, + ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT, -} IVAS_SPLIT_REND_RENDERER_SELECTION; +} ISAR_SPLIT_REND_RENDERER_SELECTION; -typedef struct _IVAS_SPLIT_REND_BITS_DATA +typedef struct _ISAR_SPLIT_REND_BITS_DATA { uint8_t *bits_buf; int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/ int32_t bits_written; int32_t bits_read; int16_t codec_frame_size_ms; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; -} IVAS_SPLIT_REND_BITS_DATA, *IVAS_SPLIT_REND_BITS_HANDLE; +} ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE; -typedef struct _IVAS_SPLIT_REND_CONFIG +typedef struct _ISAR_SPLIT_REND_CONFIG { int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ @@ -266,14 +274,15 @@ typedef struct _IVAS_SPLIT_REND_CONFIG 2 - (2dof correction. By default YAW and PITCH correction) 3 - (3dof correction. By default YAW, PITCH and ROLL correction) */ - int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ - int16_t codec_frame_size_ms; /*Codec frame size in milliseconds, only relevant with LC3plus */ - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_RENDERER_SELECTION rendererSelection; + int16_t codec_delay_ms; /* look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ + int16_t isar_frame_size_ms; /* ISAR bit stream frame size in milliseconds */ + int16_t codec_frame_size_ms; /* Codec frame size in milliseconds, only relevant with LC3plus */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection; + int16_t lc3plus_highres; -} IVAS_SPLIT_REND_CONFIG_DATA; -#endif +} ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE; /*----------------------------------------------------------------------------------* * Renderer API structures and enums @@ -314,11 +323,24 @@ typedef struct _IVAS_RENDER_CONFIG IVAS_RENDER_TYPE_OVERRIDE renderer_type_override; #endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; -#endif + ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; float directivity[IVAS_MAX_NUM_OBJECTS * 3]; + float distAtt[3]; } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; +typedef struct +{ + int16_t numSamplesPerChannel; + int16_t numChannels; + int16_t is_cldfb; + +} IVAS_REND_AudioBufferConfig; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + float *data; +} IVAS_REND_AudioBuffer; + #endif /* COMMON_API_TYPES_H */ diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 2d62e340a80cfd83c059a6875a28b44e3358aee2..4dd9b7eacc2c963a5166b5131db41a36a1d46dd9 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -51,15 +51,11 @@ /*! r: delay value in ns */ int32_t get_delay( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t io_fs, /* i : input/output sampling frequency */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - HANDLE_CLDFB_FILTER_BANK hCldfb, /* i : Handle of Cldfb analysis */ - const AUDIO_CONFIG output_config /* i : decoder output config */ -#else - HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ -#endif + const int16_t enc_dec, /* i : encoder/decoder flag */ + const int32_t io_fs, /* i : input/output sampling frequency */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + HANDLE_CLDFB_FILTER_BANK hCldfb, /* i : Handle of Cldfb analysis */ + const int16_t flag_binaural_split_coded /* i : split rendering on/off flag */ ) { int32_t delay = 0; @@ -102,18 +98,14 @@ int32_t get_delay( { delay = IVAS_DEC_DELAY_NS; -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( !flag_binaural_split_coded ) { -#endif if ( hCldfb != NULL ) { /* compensate for filterbank delay */ delay += IVAS_FB_DEC_DELAY_NS; } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) { diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 8ebe56c1853a0c0977fc652faef66a4f2842b6f2..8b01d70b56fc6a1395bbd1f154f239dd1e1f7dcb 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -123,14 +123,6 @@ typedef enum RENDERER_OMASA_MIX_EXT } RENDERER_TYPE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef enum -{ - PCM_INT16, - PCM_FLOAT32, - PCM_NOT_KNOW = 0xffff -} PCM_RESOLUTION; -#endif /*----------------------------------------------------------------------------------* * IVAS general constants @@ -1432,7 +1424,6 @@ typedef enum typedef enum { IVAS_FILTER_ORDER_1 = 1, - IVAS_FILTER_ORDER_2 = 2, IVAS_FILTER_ORDER_4 = 4, } ivas_filter_order; @@ -1465,11 +1456,8 @@ typedef enum * Amplitude Panning (EFAP, VBAP) constants *----------------------------------------------------------------------------------*/ -#define PANNING_AZI_RESOLUTION 2 -#define PANNING_ELE_RESOLUTION 5 - #define EFAP_MAX_CHAN_NUM 5 /* Maximum number of channels that constitute a polygon, 4 or 5 */ -#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. */ +#define EFAP_MAX_POLY_SET 54 /* Upper bound on number of polygons; found to be 54 in the worst case for a speaker setup of 16.0 */ #define EFAP_MODE_EFAP 0 /* EFAP Panning */ #define EFAP_MODE_EFIP 1 /* EFIP Panning */ @@ -1481,18 +1469,6 @@ typedef enum EFAP_DMX_INTENSITY } EFAP_VTX_DMX_TYPE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef enum -{ - ANY_YAW, - PITCH_ONLY, - ANY_ROLL, - PRED_ONLY, - PRED_ROLL_ONLY, - COM_GAIN_ONLY, - LR_GAIN_ONLY -} IVAS_SPLIT_REND_POSE_TYPE; -#endif #define VBAP_NUM_SEARCH_SECTORS 4 @@ -1535,66 +1511,6 @@ typedef enum #define HEADROT_SHMAT_DIM2 ( HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM ) -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split Binaural Rendering Constants - *----------------------------------------------------------------------------------*/ - -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ -#endif - -#define SPLIT_REND_DECOR_ALPHA 0.25f - -#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 -#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 -#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 -#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 -#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ - -#define SPLIT_REND_MAX_DOF 3 - -#define MAX_HEAD_ROT_POSES (2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES) -#define MAX_SPLIT_REND_MD_BANDS 20 -#define MAX_SPLIT_MD_SUBFRAMES 1 -#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS -#define COMPLEX_MD_BAND_THRESH_LOW 5 -#define SPLIT_REND_RO_MD_BAND_THRESH 4 - -#define IVAS_SPLIT_REND_NUM_QUANT_STRATS 4 -#define IVAS_SPLIT_REND_PRED_63QUANT_PNTS 63 -#define IVAS_SPLIT_REND_PRED_31QUANT_PNTS 31 -#define IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 -#define IVAS_SPLIT_REND_D_QUANT_PNTS 15 -#define IVAS_SPLIT_REND_PRED_MIN_VAL -1.4f -#define IVAS_SPLIT_REND_PRED_MAX_VAL 1.4f - -#define IVAS_SPLIT_REND_PITCH_G_MIN_VAL 0.5f -#define IVAS_SPLIT_REND_PITCH_G_MAX_VAL 1.5f -#define IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS IVAS_SPLIT_REND_D_QUANT_PNTS -#define IVAS_SPLIT_REND_D_MIN_VAL 0.0f -#define IVAS_SPLIT_REND_D_MAX_VAL 1.0f - -#define IVAS_SPLIT_REND_PRED_ROLL_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP (( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) -#define IVAS_SPLIT_REND_PRED31_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_31QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PRED31_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_31QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) -#define IVAS_SPLIT_REND_PRED63_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_63QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PRED63_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_63QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) - -#define IVAS_SPLIT_REND_D_Q_STEP (( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL ) / ( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_D_1BYQ_STEP (( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL )) -#define IVAS_SPLIT_REND_PITCH_G_Q_STEP (( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) / ( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP (( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL )) - -#define IVAS_SPLIT_REND_MAX_NUM_BYTES 4000 -#define IVAS_SPLIT_REND_HEAD_POSE_BITS 9 -#define IVAS_SPLIT_REND_DOF_BITS 2 -#define IVAS_SPLIT_REND_HQ_MODE_BITS 1 -#define IVAS_SPLIT_REND_ROT_AXIS_BITS 3 -#endif - - /*----------------------------------------------------------------------------------* * TD Binaural Object renderer *----------------------------------------------------------------------------------*/ @@ -1798,19 +1714,6 @@ typedef enum #define QUANT_STRAT_0 0 #define QUANT_STRAT_2 2 -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split rendering bitrate constants - *----------------------------------------------------------------------------------*/ - -#define SPLIT_REND_256k 256000 -#define SPLIT_REND_320k 320000 -#define SPLIT_REND_384k 384000 -#define SPLIT_REND_512k 512000 -#define SPLIT_REND_768k 768000 -#define SPLIT_REND_MAX_BRATE SPLIT_REND_768k - -#endif /*----------------------------------------------------------------------------------* * Limiter constants diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index dfedb974a1c42ea781884a8854052e0f6c006730..4bc1a817812e6b36f7990e5ca6aca1963fd815fd 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -342,10 +342,10 @@ void ivas_get_dirac_sba_max_md_bits( { *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; *metadata_max_bits = 103; - /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */ + /* OSBA needs an additional 5-bits safety margin to avoid acelp crashes */ if ( ivas_format == SBA_ISM_FORMAT ) { - ( *metadata_max_bits ) -= 3; + ( *metadata_max_bits ) -= 7; } } else if ( sba_total_brate <= IVAS_32k ) diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index d9d6b31138b4ef29c80e63a0f7678749755bfa7f..11727c4e5deee06032b2d7ff1b63db8e396058d3 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -104,6 +104,8 @@ typedef enum * input data errors * *----------------------------------------*/ IVAS_ERR_INVALID_BITSTREAM = 0x2000, + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM, + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM_CONFIG, /*----------------------------------------* * hardware errors * @@ -142,10 +144,8 @@ typedef enum IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING, IVAS_ERR_INVALID_ER_PARAM, IVAS_ERR_DIRECTIVITY_PATTERN_ID_MISSING, -#ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_ERR_LC3PLUS_INVALID_BITRATE, IVAS_ERR_INVALID_SPLIT_REND_CONFIG, -#endif /*----------------------------------------* * unknown error * @@ -244,12 +244,10 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Wrong mode"; case IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED: return "Head rotation not supported"; -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_ERR_LC3PLUS_INVALID_BITRATE: return "Specified split rendering bit rate is not supported"; case IVAS_ERR_INVALID_SPLIT_REND_CONFIG: return "Specified split rendering configuration is invalid"; -#endif case IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED: return "External orientation not supported"; case IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED: diff --git a/lib_com/ivas_error_utils.h b/lib_com/ivas_error_utils.h index ff0c96f624afa649d9d3f11e2c4e7dffc0aa5e4a..5bf677820f8bdf3af7e878b207ee6b709ea60c49 100644 --- a/lib_com/ivas_error_utils.h +++ b/lib_com/ivas_error_utils.h @@ -30,6 +30,9 @@ *******************************************************************************************************/ +#ifndef IVAS_ERROR_UTILS_H +#define IVAS_ERROR_UTILS_H + #include "options.h" #include @@ -42,9 +45,6 @@ #include #endif -#ifndef IVAS_ERROR_UTILS_H -#define IVAS_ERROR_UTILS_H - /* * Usage: * @@ -83,7 +83,6 @@ static inline ivas_error ivas_error_wrapper( const ivas_error error_code, const va_end( args ); fprintf( stderr, "\n\nIn function: %s(), %s:%d\n\n", function, file, line ); - // assert( 0 ); return error_code; } diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters.c index fcb871ff348fefb8e7be0d8cdb625e1790e03c7f..cf5a0cc049b7c6f27ea46f349ac52ad68ff6d5b7 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters.c @@ -62,7 +62,7 @@ void ivas_filters_init( int16_t i; filter_state->order = order; - if ( order == IVAS_FILTER_ORDER_2 || order == IVAS_FILTER_ORDER_1 ) + if ( order == IVAS_FILTER_ORDER_1 ) { filter_state->filt_len = order + 1; @@ -116,7 +116,6 @@ void ivas_filter_process( switch ( filter_state->order ) { case IVAS_FILTER_ORDER_1: - case IVAS_FILTER_ORDER_2: ivas_iir_2_filter( filter_state, pIn_Out, length, IVAS_FILTER_STAGE_0 ); break; case IVAS_FILTER_ORDER_4: diff --git a/lib_com/ivas_lfe_com.c b/lib_com/ivas_lfe_com.c index 83c94551e09a41e2b90bf035f8a8ba52f2475cb3..0e29fcc7d6e333536e11386cd2f3801e7d3f45a8 100644 --- a/lib_com/ivas_lfe_com.c +++ b/lib_com/ivas_lfe_com.c @@ -60,22 +60,6 @@ void ivas_lfe_lpf_select_filt_coeff( { switch ( order ) { - case IVAS_FILTER_ORDER_2: - switch ( sampling_rate ) - { - case 16000: - *ppFilt_coeff = ivas_lpf_2_butter_16k; - break; - case 32000: - *ppFilt_coeff = ivas_lpf_2_butter_32k; - break; - case 48000: - *ppFilt_coeff = ivas_lpf_2_butter_48k; - break; - default: - break; - } - break; case IVAS_FILTER_ORDER_4: switch ( sampling_rate ) { diff --git a/lib_rend/ivas_limiter.c b/lib_com/ivas_limiter.c similarity index 99% rename from lib_rend/ivas_limiter.c rename to lib_com/ivas_limiter.c index da214e568a6c32d02ef624aa517e1bc97c0b9df7..657e41683f3a7d94cc79d90eda645b82913e6a09 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_com/ivas_limiter.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_rend/ivas_lc3plus_common.c b/lib_com/ivas_osba_com.c similarity index 76% rename from lib_rend/ivas_lc3plus_common.c rename to lib_com/ivas_osba_com.c index cc350411e9d51d3ba12763571e650992b1c12eed..fcb4f8aeac3ef5b40a6d526230885ccc9a98601c 100644 --- a/lib_rend/ivas_lc3plus_common.c +++ b/lib_com/ivas_osba_com.c @@ -31,30 +31,39 @@ *******************************************************************************************************/ #include "options.h" -#include "ivas_lc3plus_common.h" -#include "ivas_error.h" -#include "lc3.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-----------------------------------------------------------------------------------------* - * Function IVAS_LC3PLUS_LC3plusErrToIvasErr() - * - * - *-----------------------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( - const LC3PLUS_Error lc3PlusError ) +#include "ivas_cnst.h" +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif + +/*! r : ISM format mode */ +ISM_MODE ivas_osba_ism_mode_select( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t nchan_ism /* i : number of input ISM's */ +) { - switch ( lc3PlusError ) + ISM_MODE ism_mode = ISM_MODE_NONE; + + switch ( nchan_ism ) { - case LC3PLUS_OK: - return IVAS_ERR_OK; - case LC3PLUS_BITRATE_ERROR: - return IVAS_ERR_LC3PLUS_INVALID_BITRATE; - default: + case 1: + if ( ivas_total_brate >= IVAS_96k ) + { + ism_mode = ISM_SBA_MODE_DISC; + } + break; + case 2: + case 3: + case 4: + if ( ivas_total_brate >= IVAS_128k ) + { + ism_mode = ISM_SBA_MODE_DISC; + } break; } - return IVAS_ERR_INTERNAL; + return ism_mode; } -#endif diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 7a8ebafe55bb60c2f18497cc13348213ba8fbd20..b534415e15956aeb24cdd2c8bc938cd729a48478 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -42,6 +42,7 @@ #include "stat_com.h" #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" +#include "ivas_stat_rend.h" #include "ivas_stat_com.h" #include "ivas_error_utils.h" @@ -318,12 +319,8 @@ ivas_error ivas_dec( ivas_error ivas_dec_setup( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); ivas_error create_sce_dec( @@ -663,12 +660,8 @@ ivas_error ivas_mc_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t idx, /* i : LS config. index */ uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); /*! r: MC format mode (MCT, McMASA, ParamMC) */ @@ -790,12 +783,8 @@ ivas_error ivas_jbm_dec_render( const uint16_t nSamplesAsked, /* i : number of samples wanted */ uint16_t *nSamplesRendered, /* o : number of samples rendered */ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); ivas_error ivas_jbm_dec_flush_renderer( @@ -807,12 +796,8 @@ ivas_error ivas_jbm_dec_flush_renderer( const MC_MODE mc_mode_old, /* i : old MC mode */ const ISM_MODE ism_mode_old, /* i : old ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); void ivas_jbm_dec_feed_tc_to_renderer( @@ -981,20 +966,14 @@ ivas_error ivas_ism_metadata_enc_create( ivas_error ivas_ism_metadata_dec_create( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE const int16_t n_ISms, /* i : number of separately coded objects */ -#else - const int16_t n_ISms, /* i : number of objects */ -#endif int32_t element_brate_tmp[] /* o : element bitrate per object */ ); -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE void ivas_ism_reset_metadata_handle_dec( ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ ); -#endif ivas_error ivas_ism_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ float *data[], /* i : input signal [channels][samples] */ @@ -1087,12 +1066,8 @@ ivas_error ivas_ism_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed on renderer change*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); ivas_error ivas_param_ism_dec_open( @@ -3212,7 +3187,8 @@ void ivas_qmetadata_enc_sid_encode( BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ IVAS_QMETADATA *q_metadata, /* i/o: metadata handle */ const int16_t masa_sid_descriptor, /* i : description of MASA SID coding structure*/ - const int16_t ivas_format /* i : ivas format */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t ivas_format /* i : ivas format */ ); /*! r: number of bits read */ @@ -3473,12 +3449,8 @@ void ivas_sba_set_cna_cng_flag( ivas_error ivas_sba_dec_reconfigure( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesFlushed, /* o : number of samples flushed */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); ivas_error ivas_sba_digest_tc( @@ -3520,6 +3492,11 @@ int16_t ivas_sba_get_nchan_metadata( const int32_t ivas_total_brate /* i : IVAS total bitrate */ ); +/*! r: number of bits in SPAR SID frame */ +int16_t ivas_sba_spar_sid_bitlen( + const int16_t nchan_transport /* i : number of transport channels */ +); + void ivas_sba_get_spar_hoa_ch_ind( const int16_t num_md_chs, /* i : number of MD channels */ const int32_t ivas_total_brate, /* i : IVAS total bitrate */ @@ -3621,7 +3598,8 @@ ivas_error ivas_dirac_enc( const int16_t input_frame, /* i : input frame length */ const int16_t dtx_vad, /* i : DTX vad flag */ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const int16_t hodirac_flag /* i : hodirac flag */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t hodirac_flag /* i : hodirac flag */ ); ivas_error ivas_dirac_config( @@ -3676,6 +3654,7 @@ void ivas_dirac_dec_read_BS( int16_t *nb_bits, /* o : number of bits read */ const int16_t last_bit_pos, /* i : last read bitstream position */ const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ + const int16_t nchan_transport, /* i : number of transport channels */ int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ); @@ -4920,12 +4899,8 @@ void ivas_masa_enc_reconfigure( ivas_error ivas_masa_dec_reconfigure( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); ivas_error ivas_masa_encode( @@ -5173,21 +5148,14 @@ void ivas_binaural_cldfb_sf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, -#endif + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ const int16_t numTimeSlots, /* i : number of time slots to process */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ -#else - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ -#endif float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ); @@ -5506,7 +5474,7 @@ void ivas_lfe_enc( ivas_error ivas_create_lfe_dec( LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ const int32_t output_Fs, /* i : output sampling rate */ - const int32_t binauralization_delay_ns /* i : additional LFE delay to sync with binaural renderer */ + const int32_t delay_ns /* i : additional LFE delay to sync other channel outputs */ ); void ivas_lfe_dec_close( @@ -5613,7 +5581,10 @@ void ivas_osba_data_close( SBA_ISM_DATA_HANDLE *hSbaIsmData /* i/o: OSBA rendering handle */ ); - +ISM_MODE ivas_osba_ism_mode_select( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t nchan_ism /* i : number of input ISM's */ +); /*----------------------------------------------------------------------------------* * OMASA prototypes *---------------------------------------------------------------------------------*/ @@ -5633,12 +5604,8 @@ ivas_error ivas_omasa_enc_config( ivas_error ivas_omasa_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ); void ivas_omasa_set_config( @@ -5933,6 +5900,54 @@ int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ ); +void Euler2Quat( + const float yaw, /* i : yaw (x) */ + const float pitch, /* i : pitch (y) */ + const float roll, /* i : roll (z) */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +); + +float deg2rad( + float degrees +); + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); + +/*----------------------------------------------------------------------------------* + * Limiter prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_limiter_open( + IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ + const int16_t num_channels, /* i : number of I/O channels */ + const int32_t sampling_rate /* i : sampling rate for processing */ +); + +void ivas_limiter_close( + IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ +); + +void ivas_limiter_dec +( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ + const int16_t num_channels, /* i : number of channels to be processed */ + const int16_t output_frame, /* i : number of samples per channel in the buffer */ + const int16_t BER_detect /* i : BER detect flag */ +); + +void limiter_process( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ + const float threshold, /* i : signal amplitude above which limiting starts to be applied */ + const int16_t BER_detect, /* i : BER detect flag */ + int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ +); /* clang-format on */ diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 68169f10d49b4a1cc4bc5e5ca279438ae06d6571..ffd5d578de259c6679e12d2c6af3dc5e88102f84 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -3079,21 +3079,6 @@ const float ivas_lpf_4_butter_48k_sos[IVAS_BIQUAD_FILT_LEN << 2] = 1.00000000471366f, 1.f , -1.98677297369091f, 0.987060670205863f }; -const float ivas_lpf_2_butter_16k[IVAS_BIQUAD_FILT_LEN << 1] = -{ - 0.000628720643081143f, 0.00125744128616229f, 0.000628720643081143f, 1.f, -1.92783286977036f, 0.930347752342683f -}; - -const float ivas_lpf_2_butter_32k[IVAS_BIQUAD_FILT_LEN << 1] = -{ - 0.000159990787823749f, 0.000319981575647499f, 0.000159990787823749f, 1.f, -1.96390539174033f, 0.964545354891623f -}; - -const float ivas_lpf_2_butter_48k[IVAS_BIQUAD_FILT_LEN << 1] = -{ - 7.15317998432330e-05f, 0.000143063599686466f, 7.15317998432330e-05f, 1.f, -1.97593552482925f, 0.976221652028620f -}; - const ivas_lfe_freq_models ivas_str_lfe_freq_models = { { 16384, 14924, 13463, 12003, 10542, 9082, 7622, 6161, diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 2cfecaefb345635cb19786a5be26e4a62c9b0bf0..59830626488ac34efaf94539acae805bc4c1c309 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -348,9 +348,6 @@ extern const int16_t Param_ISM_band_grouping[MAX_PARAM_ISM_NBANDS + 1]; extern const float ivas_lpf_4_butter_16k_sos[IVAS_BIQUAD_FILT_LEN << 2]; extern const float ivas_lpf_4_butter_32k_sos[IVAS_BIQUAD_FILT_LEN << 2]; extern const float ivas_lpf_4_butter_48k_sos[IVAS_BIQUAD_FILT_LEN << 2]; -extern const float ivas_lpf_2_butter_16k[IVAS_BIQUAD_FILT_LEN << 1]; -extern const float ivas_lpf_2_butter_32k[IVAS_BIQUAD_FILT_LEN << 1]; -extern const float ivas_lpf_2_butter_48k[IVAS_BIQUAD_FILT_LEN << 1]; extern const float ivas_lfe_window_coeff_48k[IVAS_LFE_FADE_LEN_48K]; extern const float ivas_lfe_window_coeff_32k[IVAS_LFE_FADE_LEN_32K]; diff --git a/lib_com/ivas_rotation_com.c b/lib_com/ivas_rotation_com.c new file mode 100644 index 0000000000000000000000000000000000000000..45b78e3984c52827eb88c4904438c255a9c41e2a --- /dev/null +++ b/lib_com/ivas_rotation_com.c @@ -0,0 +1,135 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_cnst.h" +#include +#include +#include "options.h" +#include +#include "cnst.h" +#include "prot.h" +#include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +/*------------------------------------------------------------------------- + * Euler2Quat() + * + * Calculate corresponding Quaternion from Euler angles in radians + *------------------------------------------------------------------------*/ + +void Euler2Quat( + const float yaw, /* i : yaw (x) */ + const float pitch, /* i : pitch (y) */ + const float roll, /* i : roll (z) */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +) +{ + float cr = cosf( roll * 0.5f ); + float sr = sinf( roll * 0.5f ); + float cp = cosf( pitch * 0.5f ); + float sp = sinf( pitch * 0.5f ); + float cy = cosf( yaw * 0.5f ); + float sy = sinf( yaw * 0.5f ); + quat->w = cr * cp * cy + sr * sp * sy; + quat->x = sr * cp * cy - cr * sp * sy; + quat->y = sr * cp * sy + cr * sp * cy; + quat->z = cr * cp * sy - sr * sp * cy; + + return; +} + + +/*------------------------------------------------------------------------- + * Quat2EulerDegree() + * + * Quaternion handling: calculate corresponding Euler angles in degrees + *------------------------------------------------------------------------*/ + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +) +{ + if ( quat.w != -3.0 ) + { + float p; + *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) ); + p = 2 * ( quat.w * quat.y - quat.z * quat.x ); + p = max( -1.0f, min( 1.0f, p ) ); + *pitch = asinf( p ); + *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) ); + *yaw *= _180_OVER_PI; + *pitch *= _180_OVER_PI; + *roll *= _180_OVER_PI; + } + else + { + /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention + * + * yaw: rotate scene counter-clockwise in the horizontal plane + * pitch: rotate scene in the median plane, increase elevation with positive values + * roll: rotate scene from the right ear to the top + */ + *yaw = quat.z; + *pitch = quat.y; + *roll = quat.x; + } + + return; +} + + +/*------------------------------------------------------------------------- + * deg2rad() + * + * Converts degrees to normalized radians + *------------------------------------------------------------------------*/ + +float deg2rad( + float degrees ) +{ + while ( degrees >= 180.0f ) + { + degrees = degrees - 360.0f; + } + while ( degrees <= -180.0f ) + { + degrees = degrees + 360.0f; + } + + return PI_OVER_180 * degrees; +} diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index cb573d7f28580224703b477feb63cbef0a5b8c79..4c5313de3ba57f41df793afed36af6726ead402d 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -158,6 +158,27 @@ int16_t ivas_sba_get_nchan( return ( nb_channels ); } +/*-------------------------------------------------------------------* + * ivas_sba_spar_sid_bitlen() + * + * Get number of bits in SPAR SID frame + *-------------------------------------------------------------------*/ + +/*! r: number of bits in SPAR SID frame */ +int16_t ivas_sba_spar_sid_bitlen( + const int16_t nchan_transport /* i : number of transport channels */ +) +{ + int16_t num_bits; + + num_bits = SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND; + if ( nchan_transport > 1 ) + { + num_bits -= 2; + } + + return num_bits; +} /*-------------------------------------------------------------------* * ivas_sba_get_nchan_metadata() diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 434ddc608085c3a2f054033d4824c09d4e319f10..23645a77dc88154235066ef245a229ee81eeebb9 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -782,6 +782,4 @@ typedef struct ivas_param_ism_data_structure float last_cardioid_left[MAX_NUM_OBJECTS]; } PARAM_ISM_CONFIG_DATA, *PARAM_ISM_CONFIG_HANDLE; - - #endif /* IVAS_STAT_COM */ diff --git a/lib_com/options.h b/lib_com/options.h index 279f94dcc2f1c0565a63429b26271165a7e959e5..facd7a4208e9f6b3c18fc2e4589043c0cad349e6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,9 +154,13 @@ /* only BE switches wrt selection floating point code */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -/*#define SPLIT_REND_WITH_HEAD_ROT */ /* Dlb,FhG: Split Rendering contributions 21 and 35 */ -#define FIX_1060_USAN_ARRAY_BOUNDS /* FhG: issue 1060: USAN array-bounds errors */ +//#define FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT /* Orange issue 1031 : new fix point hrtf binary file format */ +//#define FIX_CREND_SIMPLIFY_CODE /* Ora : simplify line code in crend */ +#define FLOAT_FIX_POINT_HRTF_FILE_FORMAT /* allows reading floation or fix point hrtf binary file format */ + + +#define FIX_1099_JBM_MD_HANDLE_ALLOC /* VA: issue 1099: Limit the allocation of `hJbmMetadata` handle to MASA and OMASA only */ #define AMBISONICS_CONVENTIONS @@ -167,10 +171,7 @@ /* any switch which is non-be wrt selection floating point code */ /* all switches in this category should start with "NONBE_" */ -#define NONBE_FIX_1045_ISM_BITRATE_SWITCHING /* Eri: Difference between ROM/File HRTF in ISM bitrate switching */ -#define NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES /* Philips: issue 1067: QuaternionSlerp inaccuracies in corner cases */ -#define NONBE_FIX_1065_ISM_MD_HANDLE /* VA: issue 1065: Allocate only the necessary number of ISM MD decoder handles. */ - +#define NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT /* fix 1070 USAN: nullptr-with-offset and Segfaults in 7_1_4 to BINAURAL and BINAURAL_ROOM_REVERB decoding with bitrate switching and head rotation*/ /* ##################### End NON-BE switches ########################### */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 1e08bbfec1a493099b8b17963340d0cf893bb429..d26a2a42abe0d51e2befdf8e7a241ff3592f2ddc 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -724,14 +724,11 @@ int16_t lev_dur( /*! r: delay value in ns */ int32_t get_delay( - const int16_t enc_dec, /* i : encoder/decoder flag */ - const int32_t io_fs, /* i : input/output sampling frequency */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - const AUDIO_CONFIG output_config /* i : decoder output config */ -#endif + const int16_t enc_dec, /* i : encoder/decoder flag */ + const int32_t io_fs, /* i : input/output sampling frequency */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + HANDLE_CLDFB_FILTER_BANK hCldfb, /* i : Handle of Cldfb analysis */ + const int16_t flag_binaural_split_coded /* i : split rendering on/off flag */ ); void decision_matrix_enc( diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index 8ed19f9de0d572e68721b0f3c1b9211a8b543813..802a7ec3021ba96fc0f16ebf025039454aac6237 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -150,7 +150,7 @@ void open_decoder_LPD( { st->gamma = GAMMA16k; } - else if ( st->sr_core > INT_FS_16k && st->element_mode == IVAS_CPE_MDCT ) + else if ( st->element_mode > EVS_MONO && st->sr_core > INT_FS_16k ) { st->gamma = GAMMA16k; } diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 0b005615dda02cda6fb6c684da6a1d40590e220b..1c317c20b63dee2abd0c78e2151851a33f18da76 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -42,16 +42,23 @@ #include "ivas_rom_dec.h" #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_rom_dec.h" -#include "lib_rend.h" -#endif #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" +/*------------------------------------------------------------------------- + * Local constants + *------------------------------------------------------------------------*/ + +#define REVERB_INPUT_DOWNMIX_CHANNELS ( 11 ) +/* Downmix table for sparse frequency domain reverberator */ +const float dmxmtx_table[BINAURAL_CHANNELS][REVERB_INPUT_DOWNMIX_CHANNELS] = { + { 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 }, +}; + /*------------------------------------------------------------------------- * ivas_binRenderer_filterModule() * @@ -64,12 +71,8 @@ static void ivas_binRenderer_filterModule( float CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals */ float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */ const int16_t numTimeSlots, /* i : number of time slots to process */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ - const int16_t pos_idx /* i : pose index */ -#else - BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ -#endif + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ + const int16_t pos_idx /* i : pose index */ ) { int16_t bandIdx, k, chIdx, tapIdx; @@ -80,13 +83,8 @@ static void ivas_binRenderer_filterModule( { for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx][0] ); filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx][0] ); -#else - filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx][0] ); - filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx][0] ); -#endif filterTapsLeftRealPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx]; filterTapsLeftImagPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx]; @@ -141,19 +139,12 @@ static ivas_error ivas_binRenderer_convModuleOpen( const int16_t renderer_type, const int16_t isLoudspeaker, const AUDIO_CONFIG input_config, -#ifdef SPLIT_REND_WITH_HEAD_ROT const HRTFS_FASTCONV_HANDLE hHrtf, - const int16_t num_poses -#else - const HRTFS_FASTCONV_HANDLE hHrtf -#endif -) + const int16_t num_poses ) { int16_t bandIdx, chIdx; BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif /*-----------------------------------------------------------------* * prepare library opening @@ -264,7 +255,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( hBinRenConvModule->filterStatesLeftReal = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); @@ -313,44 +303,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } -#else - - if ( ( hBinRenConvModule->filterStatesLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - if ( ( hBinRenConvModule->filterStatesLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) - { - if ( ( hBinRenConvModule->filterStatesLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - if ( ( hBinRenConvModule->filterStatesLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) - { - if ( ( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - if ( ( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - } - } -#endif /* SPLIT_REND_WITH_HEAD_ROT */ /* set memories */ for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) @@ -391,11 +343,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { -#ifndef SPLIT_REND_WITH_HEAD_ROT - /* set the memories to zero */ - set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); - set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); -#endif + if ( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftBRIRReal[bandIdx][tmp]; @@ -413,11 +361,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } else { -#ifndef SPLIT_REND_WITH_HEAD_ROT - /* set the memories to zero */ - set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTaps ); - set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTaps ); -#endif if ( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal[bandIdx][tmp]; @@ -460,7 +403,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) @@ -473,7 +415,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } -#endif hBinRenderer->hBinRenConvModule = hBinRenConvModule; @@ -895,7 +836,7 @@ static void ivas_binaural_obtain_DMX( for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { - float dmxConst = hBinRenderer->hReverb->dmxmtx[chOutIdx][chIdx]; + float dmxConst = dmxmtx_table[chOutIdx][chIdx]; for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -999,7 +940,6 @@ static void ivas_binaural_obtain_DMX( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- * ivas_rend_openCldfbRend() * @@ -1090,7 +1030,6 @@ ivas_error ivas_rend_openCldfbRend( return error; } -#endif /*------------------------------------------------------------------------- @@ -1104,7 +1043,7 @@ ivas_error ivas_binRenderer_open( ) { BINAURAL_RENDERER_HANDLE hBinRenderer; - int16_t convBand, chIdx, k; + int16_t convBand, k; ivas_error error; error = IVAS_ERR_OK; @@ -1127,20 +1066,18 @@ ivas_error ivas_binRenderer_open( hBinRenderer->rotInCldfb = 1; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses + 1; + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses + 1; #else - hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; #endif } else { hBinRenderer->numPoses = 1; } -#endif /* Declare some common variables needed for renderer */ /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */ @@ -1185,11 +1122,7 @@ ivas_error ivas_binRenderer_open( IVAS_OUTPUT_SETUP out_setup; /* Allocate memories and buffers needed for convolutional module in CICP19 */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1210,11 +1143,7 @@ ivas_error ivas_binRenderer_open( else { /* Allocate memories and buffers needed for convolutional module */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1259,18 +1188,6 @@ ivas_error ivas_binRenderer_open( { return error; } - - /* initialize the dmx matrix */ - if ( hBinRenderer->nInChannels != HOA3_CHANNELS ) - { - for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) - { - for ( k = 0; k < hBinRenderer->nInChannels; k++ ) - { - hBinRenderer->hReverb->dmxmtx[chIdx][k] = dmxmtx_table[chIdx][k]; - } - } - } } else { @@ -1314,18 +1231,12 @@ ivas_error ivas_binRenderer_open( *------------------------------------------------------------------------*/ static void ivas_binRenderer_convModuleClose( -#ifdef SPLIT_REND_WITH_HEAD_ROT BINAURAL_RENDERER_HANDLE *hBinRenderer, /* i/o: fastconv binaural renderer handle */ const int16_t num_poses /* i : number of poses */ -#else - BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ -#endif ) { int16_t bandIdx, chIdx; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t posIdx; -#endif BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; @@ -1362,7 +1273,6 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterTapsRightImag ); hBinRenConvModule->filterTapsRightImag = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( posIdx = 0; posIdx < num_poses; posIdx++ ) { for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) @@ -1394,31 +1304,6 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterStatesLeftImag ); hBinRenConvModule->filterStatesLeftImag = NULL; -#else - for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) - { - for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) - { - free( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] ); - hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = NULL; - - free( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] ); - hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = NULL; - } - - free( hBinRenConvModule->filterStatesLeftReal[bandIdx] ); - hBinRenConvModule->filterStatesLeftReal[bandIdx] = NULL; - - free( hBinRenConvModule->filterStatesLeftImag[bandIdx] ); - hBinRenConvModule->filterStatesLeftImag[bandIdx] = NULL; - } - - free( hBinRenConvModule->filterStatesLeftReal ); - hBinRenConvModule->filterStatesLeftReal = NULL; - - free( hBinRenConvModule->filterStatesLeftImag ); - hBinRenConvModule->filterStatesLeftImag = NULL; -#endif free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; @@ -1444,11 +1329,7 @@ void ivas_binRenderer_close( if ( ( *hBinRenderer )->hBinRenConvModule != NULL ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_binRenderer_convModuleClose( hBinRenderer, ( *hBinRenderer )->numPoses ); -#else - ivas_binRenderer_convModuleClose( hBinRenderer ); -#endif } if ( ( *hBinRenderer )->hReverb != NULL ) @@ -1611,13 +1492,8 @@ void ivas_binaural_cldfb( { float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#else - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; /* Implement a 5 msec loops */ @@ -1648,7 +1524,6 @@ void ivas_binaural_cldfb( idx_in++; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*LFE handling for split rendering cases*/ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { @@ -1659,25 +1534,22 @@ void ivas_binaural_cldfb( idx_in++; } - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } -#endif } /* Implement binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, -#ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, -#endif + &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hCombinedOrientationData, JBM_CLDFB_SLOTS_IN_SUBFRAME, #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG @@ -1686,7 +1558,6 @@ void ivas_binaural_cldfb( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t pos_idx; @@ -1718,13 +1589,12 @@ void ivas_binaural_cldfb( maxBand ); } - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); } } } } -#endif /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * MAX_PARAM_SPATIAL_SUBFRAMES ); @@ -1739,13 +1609,8 @@ void ivas_binaural_cldfb( for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; -#else - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; -#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] ); @@ -1771,13 +1636,8 @@ void ivas_binaural_cldfb_sf( { float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#else - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; int16_t slots_to_render, first_sf, last_sf; int16_t slot_index_start, slot_index_start_cldfb; @@ -1824,7 +1684,6 @@ void ivas_binaural_cldfb_sf( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*LFE handling for split rendering cases*/ if ( ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) @@ -1836,27 +1695,22 @@ void ivas_binaural_cldfb_sf( idx_in++; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } -#endif } -#endif } /* Implement binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, -#ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, -#endif + &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG @@ -1867,7 +1721,6 @@ void ivas_binaural_cldfb_sf( Cldfb_RealBuffer, Cldfb_ImagBuffer ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t pos_idx; @@ -1877,13 +1730,12 @@ void ivas_binaural_cldfb_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); } } } } -#endif /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ); @@ -1896,13 +1748,8 @@ void ivas_binaural_cldfb_sf( for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; -#else - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; -#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_index_start_cldfb * maxBand] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); @@ -1926,38 +1773,28 @@ void ivas_binaural_cldfb_sf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, -#endif COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ const int16_t numTimeSlots, /* i : number of time slots to render */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ -#else - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ -#endif - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ) { int16_t chIdx, k; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx, num_poses; -#endif + float RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; push_wmops( "fastconv_binaural_rendering" ); -#ifdef SPLIT_REND_WITH_HEAD_ROT num_poses = hBinRenderer->numPoses; -#endif /* Compute Convolution */ /* memory reset for the binaural output */ -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) @@ -1969,16 +1806,15 @@ void ivas_binRenderer( } } } -#else - for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + + for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) { for ( k = 0; k < numTimeSlots; k++ ) { - set_zero( Cldfb_RealBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); - set_zero( Cldfb_ImagBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + mvr2r( RealBuffer[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + mvr2r( ImagBuffer[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); } } -#endif /* Head rotation in HOA3 or CICPx */ if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb ) @@ -2008,14 +1844,8 @@ void ivas_binRenderer( ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, 0 ); -#else - ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*TODO : move this to a separate function*/ if ( pMultiBinPoseData != NULL ) { if ( pMultiBinPoseData->num_poses > 1 ) @@ -2026,12 +1856,32 @@ void ivas_binRenderer( if ( hCombinedOrientationData && hBinRenderer->rotInCldfb ) { Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; - Quaternions_rel.w = -3.0f; /*euler*/ - Quaternions_abs.w = -3.0f; /*euler*/ - Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + Quaternions_rel.w = -3.0f; /*euler*/ + Quaternions_abs.w = -3.0f; + + if ( hCombinedOrientationData->shd_rot_max_order == 0 ) + { + /*HOA signal already rotated by DirAC*/ + Quaternions_abs.x = 0.0f; + Quaternions_abs.y = 0.0f; + Quaternions_abs.z = 0.0f; + } + else + { + /*euler*/ + Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + } for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) { + for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + mvr2r( RealBuffer_local[chIdx][k], RealBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + mvr2r( ImagBuffer_local[chIdx][k], ImagBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } Quaternions_rel.x = pMultiBinPoseData->relative_head_poses[pos_idx][0] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][0]; Quaternions_rel.y = pMultiBinPoseData->relative_head_poses[pos_idx][1] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][1]; Quaternions_rel.z = pMultiBinPoseData->relative_head_poses[pos_idx][2] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][2]; @@ -2039,7 +1889,7 @@ void ivas_binRenderer( Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; - QuatToRotMat( Quaternions_rel, Rmat_local ); + QuatToRotMat( Quaternions_abs, Rmat_local ); if ( hBinRenderer->hInputSetup->is_loudspeaker_setup ) { @@ -2052,31 +1902,9 @@ void ivas_binRenderer( ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, pos_idx ); } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - if ( hPostRendHeadTrackData != NULL ) - { - IVAS_QUATERNION *Quaternions_new1; - IVAS_QUATERNION Quaternions_new; - Quaternions_new1 = &hPostRendHeadTrackData->Quaternions[hPostRendHeadTrackData->num_quaternions++]; - Quaternions_new.w = -3.0f; /*euler*/ - Quat2EulerDegree( *Quaternions_new1, &Quaternions_new.z, &Quaternions_new.y, &Quaternions_new.x ); /*order in Quat2Euler seems to be reversed ?*/ - Quaternions_rel.x = Quaternions_new.x - Quaternions_abs.x; - Quaternions_rel.y = Quaternions_new.y - Quaternions_abs.y; - Quaternions_rel.z = Quaternions_new.z - Quaternions_abs.z; - Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; - Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; - Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; - - QuatToRotMat( Quaternions_rel, Rmat_local ); - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, 3 ); - ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[num_poses], Cldfb_ImagBuffer_Binaural[num_poses], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, num_poses ); - } -#endif } } } -#endif /* Obtain the binaural dmx and compute the reverb */ if ( hBinRenderer->hReverb != NULL ) @@ -2104,18 +1932,12 @@ void ivas_binRenderer( { for ( k = 0; k < numTimeSlots; k++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { /* Combine first and second parts to generate binaural output signal with room effect */ v_add( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band ); v_add( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band ); } -#else - /* Combine first and second parts to generate binaural output signal with room effect */ - v_add( Cldfb_RealBuffer_Binaural[chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); - v_add( Cldfb_ImagBuffer_Binaural[chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); -#endif } } } @@ -2125,7 +1947,6 @@ void ivas_binRenderer( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- * ivas_rend_CldfbMultiBinRendProcess() * @@ -2170,7 +1991,7 @@ void ivas_rend_CldfbMultiBinRendProcess( if ( ( *pCombinedOrientationData ) != NULL ) { - if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0]; for ( i = 0; i < 3; i++ ) @@ -2188,13 +2009,14 @@ void ivas_rend_CldfbMultiBinRendProcess( head_track_post.num_quaternions = 0; head_track_post.shd_rot_max_order = -1; head_track_post.Quaternions[0] = ivas_split_rend_get_sf_rot_data( pHeadRotData->headPositionsPostRend, sf_idx ); -#endif +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, &head_track_post, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); #else ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); #endif + for ( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ ) { for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) @@ -2211,4 +2033,3 @@ void ivas_rend_CldfbMultiBinRendProcess( return; } -#endif diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index fd7ce6c8037640251469e0ae619931b6c30f26e0..b8eee14f61c1faba18895011d407fb8a6ec02f58 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -270,7 +270,7 @@ ivas_error ivas_corecoder_dec_reconfig( } else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) { - if ( ( error = mct_dec_reconfigure( st_ivas, st_ivas->nchan_transport != nchan_transport_old ) ) != IVAS_ERR_OK ) + if ( ( error = mct_dec_reconfigure( st_ivas, nchan_transport_real != nchan_transport_old ) ) != IVAS_ERR_OK ) { return error; } @@ -351,7 +351,7 @@ ivas_error ivas_corecoder_dec_reconfig( * Set CNA/CNG flags *-----------------------------------------------------------------*/ - if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { ivas_sba_set_cna_cng_flag( st_ivas ); } diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 842bac31c5327277e0d5489c8c2d127a43c1d2ba..4be1a931edc72575baa433e89cc78b3242761eaa 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -765,6 +765,7 @@ ivas_error ivas_dirac_dec_config( int16_t need_parambin; int16_t dec_param_estim_old; int16_t dec_param_estim_new; + int16_t num_poses, pos_idx; error = IVAS_ERR_OK; @@ -775,6 +776,12 @@ ivas_error ivas_dirac_dec_config( hodirac_flag = ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); dec_param_estim_old = ( dec_config_flag == DIRAC_RECONFIGURE ) ? st_ivas->hDirAC->hConfig->dec_param_estim : FALSE; + num_poses = 1; + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + } + sparfoa_flag = 0; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA && st_ivas->ivas_format == SBA_FORMAT && !hodirac_flag ) { @@ -810,11 +817,7 @@ ivas_error ivas_dirac_dec_config( if ( !need_parambin ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); -#else - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); -#endif } need_dirac_rend = 0; @@ -866,11 +869,7 @@ ivas_error ivas_dirac_dec_config( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0] == NULL ) -#else - if ( st_ivas->hDiracDecBin == NULL ) -#endif { if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas, &( st_ivas->hHrtfParambin ) ) ) != IVAS_ERR_OK ) { @@ -880,71 +879,43 @@ ivas_error ivas_dirac_dec_config( else { /* This is required to keep BE in rate switching. This probably means that 1TC and 2TC MASA perform differently. */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params != NULL && !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nSCE > 0 ) ) -#else - if ( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params != NULL && !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nSCE > 0 ) ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_decorr_close( &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ); -#else - ivas_dirac_dec_decorr_close( &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ); -#endif } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) -#endif { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT /* copy td-decorr flag to split renderer side rendereres */ - for ( int16_t pos_idx = 1; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 1; pos_idx < num_poses; pos_idx++ ) { st_ivas->hDiracDecBin[pos_idx]->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; } if ( !st_ivas->hDiracDecBin[0]->useTdDecorr ) -#else - if ( !st_ivas->hDiracDecBin->useTdDecorr ) -#endif - { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params == NULL ) -#else - if ( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params == NULL ) -#endif { float frequency_axis[CLDFB_NO_CHANNELS_MAX]; ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, -#else - if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, -#endif - DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_dec_decorr_open( + &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( int16_t pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); } -#else - st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif } } } @@ -1001,6 +972,7 @@ void ivas_dirac_dec_read_BS( int16_t *nb_bits, /* o : number of bits read */ const int16_t last_bit_pos, /* i : last read bitstream position */ const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ + const int16_t nchan_transport, /* i : number of transport channels */ int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ) { @@ -1034,7 +1006,8 @@ void ivas_dirac_dec_read_BS( } } - *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ); + *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), nchan_transport, NULL, SBA_FORMAT ); + 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]; @@ -1082,7 +1055,7 @@ void ivas_dirac_dec_read_BS( 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 ); + st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS - SBA_PLANAR_BITS - SBA_ORDER_BITS ); /* 1 bit flag for signaling metadata to read */ b = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits )++; @@ -1102,7 +1075,7 @@ void ivas_dirac_dec_read_BS( } } - *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ); + *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), nchan_transport, NULL, SBA_FORMAT ); 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]; @@ -1676,13 +1649,8 @@ void ivas_dirac_dec_render_sf( /*CLDFB: last output channels reserved to LFT for CICPx*/ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#else - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif float Cldfb_RealBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; int16_t index, num_freq_bands; @@ -2317,13 +2285,8 @@ void ivas_dirac_dec_render_sf( for ( l = 0; l < hSpatParamRendCom->num_freq_bands; l++ ) { -#ifdef FIX_1060_USAN_ARRAY_BOUNDS Cldfb_RealBuffer[j2][k][l] += g * *( tc_re++ ); Cldfb_ImagBuffer[j2][k][l] += g * *( tc_im++ ); -#else - Cldfb_RealBuffer[j2][0][k * hSpatParamRendCom->num_freq_bands + l] += g * *( tc_re++ ); - Cldfb_ImagBuffer[j2][0][k * hSpatParamRendCom->num_freq_bands + l] += g * *( tc_im++ ); -#endif } w1 += hSpatParamRendCom->num_freq_bands; } @@ -2339,37 +2302,29 @@ void ivas_dirac_dec_render_sf( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { for ( ch = 0; ch < st_ivas->hBinRenderer->nInChannels; ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } -#endif /* Perform binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, -#ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, -#endif - - st_ivas->hCombinedOrientationData, - hSpatParamRendCom->subframe_nbslots[subframe_idx], + ivas_binRenderer( st_ivas->hBinRenderer, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hCombinedOrientationData, hSpatParamRendCom->subframe_nbslots[subframe_idx], #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG NULL, #endif Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); -#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t pos_idx; @@ -2379,13 +2334,12 @@ void ivas_dirac_dec_render_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); } } } } -#endif /* Inverse CLDFB*/ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) @@ -2396,13 +2350,8 @@ void ivas_dirac_dec_render_sf( for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i]; ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i]; -#else - RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; - ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; -#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index 7afa191edbd15d72c047461ba1e2709e3a9b818a..1e90b6f3ba5d4ccb275b990bd46a82a481ef174d 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -51,6 +51,11 @@ #include "wmc_auto.h" #include "rom_dec.h" +/*-----------------------------------------------------------------------* + * Local constants + *-----------------------------------------------------------------------*/ + +#define SQRT_EPSILON 3.16227755e-08 /* square root of EPSILON */ /*-------------------------------------------------------------------* * ivas_dirac_dec_output_synthesis_cov_open() @@ -577,8 +582,7 @@ int16_t computeMixingMatrices( *-----------------------------------------------------------------*/ maximum( svd_s_buffer, lengthCx, &limit ); - limit = limit * reg_Sx + EPSILON; - + limit = (float) max( limit * reg_Sx, SQRT_EPSILON ); for ( i = 0; i < lengthCx; ++i ) { svd_s_buffer[i] = ( ( svd_s_buffer[i] > limit ) ? svd_s_buffer[i] : limit ); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 68badb98dd55b3bd87a79a79f274fb25da033ff5..64cddf0e12791efe63c8eeabfd5ace8c84d7380b 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -37,9 +37,6 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "prot.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "common_api_types.h" -#endif #include #include #include @@ -57,213 +54,29 @@ static ivas_error ivas_read_format( Decoder_Struct *st_ivas, int16_t *num_bits_r static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas ); -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas ); - - -/*-------------------------------------------------------------------* - * ivas_dec_reconfig_split_rend() - * - * IVAS decoder split rend reconfig - *-------------------------------------------------------------------*/ - -static ivas_error ivas_dec_reconfig_split_rend( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -) -{ - ivas_error error; - int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; - SPLIT_REND_WRAPPER *hSplitRendWrapper; -#ifndef SPLIT_REND_WITH_HEAD_ROT - CLDFB_TYPE cldfbMode; -#endif - - hSplitRendWrapper = &st_ivas->hSplitBinRend.splitrend; - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = 0; - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || - st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - cldfb_in_flag = 1; - } - - ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); - - isCldfbNeeded = 0; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#else - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - cldfb_in_flag = 0; - } -#endif - - if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - if ( cldfb_in_flag == 0 ) - { - isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif - } - else if ( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) - { - isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_SYNTHESIS; -#endif - } - else if ( pcm_out_flag && cldfb_in_flag ) - { - isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_SYNTHESIS; -#endif - } - } - - if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) - { - if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); - } - - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } - - num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; - - for ( ch = 0; ch < num_ch; ch++ ) - { -#ifndef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), cldfbMode, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) -#else - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) -#endif - - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#endif - } - else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) - { - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) - { - deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) - { - deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); - hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; - } - } -#endif - - free( hSplitRendWrapper->hCldfbHandles ); - hSplitRendWrapper->hCldfbHandles = NULL; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && - ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) ) -#else - if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) -#endif - { - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) - { - if ( hSplitRendWrapper->hTdRendHandles[i] != NULL ) - { - hSplitRendWrapper->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &hSplitRendWrapper->hTdRendHandles[i] ); - } - } - } - - return IVAS_ERR_OK; -} - +static AUDIO_CONFIG ivas_set_output_config_from_sba_order( const int16_t sba_order ); -/*-------------------------------------------------------------------* - * ivas_dec_init_split_rend() - * - * IVAS decoder split rend init - *-------------------------------------------------------------------*/ -static ivas_error ivas_dec_init_split_rend( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -) +static AUDIO_CONFIG ivas_set_output_config_from_sba_order( const int16_t sba_order ) { - ivas_error error; - int16_t cldfb_in_flag, pcm_out_flag; - - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = 0; - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || - st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - cldfb_in_flag = 1; - } - - ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); - - if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend.splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) - { - if ( ( st_ivas->hSplitBinRend.hCldfbDataOut = (IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); - } - } - - if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) - { - return error; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) + AUDIO_CONFIG output_config; + output_config = IVAS_AUDIO_CONFIG_HOA3; + switch ( sba_order ) { - cldfb_in_flag = 0; + case SBA_FOA_ORDER: + output_config = IVAS_AUDIO_CONFIG_FOA; + break; + case SBA_HOA2_ORDER: + output_config = IVAS_AUDIO_CONFIG_HOA2; + break; + case SBA_HOA3_ORDER: + output_config = IVAS_AUDIO_CONFIG_HOA3; + break; + default: + assert( 0 ); } -#endif - - error = ivas_split_renderer_open( &st_ivas->hSplitBinRend.splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize ); - return error; + return output_config; } -#endif - /*-------------------------------------------------------------------* * ivas_dec_setup() @@ -272,14 +85,10 @@ static ivas_error ivas_dec_init_split_rend( *-------------------------------------------------------------------*/ ivas_error ivas_dec_setup( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ - void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ ) { int16_t k, idx, num_bits_read; @@ -333,11 +142,7 @@ ivas_error ivas_dec_setup( st_ivas->nchan_ism = nchan_ism; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -351,15 +156,16 @@ ivas_error ivas_dec_setup( /* read Ambisonic (SBA) order */ st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + st_ivas->hDecoderConfig->output_config = ivas_set_output_config_from_sba_order( st_ivas->sba_order ); + st_ivas->hDecoderConfig->nchan_out = audioCfg2channels( st_ivas->hDecoderConfig->output_config ); + } num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -391,11 +197,19 @@ ivas_error ivas_dec_setup( if ( st_ivas->nchan_ism > 0 ) { /* the input_ivas_format should be MASA_ISM_FORMAT, but we cannot initialize it now */ - if ( st_ivas->nchan_transport == 2 && st_ivas->nchan_ism == 3 ) + /* info about the number of objects: + '00' - MASA format at the encoder + '01' - MASA_ISM_FORMAT at the encoder, with 4 objects + '10' - MASA_ISM_FORMAT at the encoder, with 3 objects + '11' - MASA_ISM_FORMAT at the encoder, with 1 or 2 objects + reading if 1 or 2 objects is performed later + */ + st_ivas->nchan_ism = 5 - st_ivas->nchan_ism; + if ( st_ivas->nchan_transport == 1 && st_ivas->nchan_ism == 2 ) { - st_ivas->nchan_ism = 4; + st_ivas->nchan_ism = 1; } - /* for MASA_ISM_FORMAT at input the number of MASA transport channels is always 2 */ + /* for MASA_ISM_FORMAT at input the number of MASA transport channels is always 2 and the corresponding bit is not used here*/ st_ivas->nchan_transport = 2; element_mode_flag = 1; } @@ -414,11 +228,7 @@ ivas_error ivas_dec_setup( else { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -426,12 +236,7 @@ ivas_error ivas_dec_setup( } else { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif - { return error; } @@ -452,11 +257,7 @@ ivas_error ivas_dec_setup( /* reconfigure in case a change of operation mode is detected */ if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -468,30 +269,25 @@ ivas_error ivas_dec_setup( /* the number of objects is written at the end of the bitstream, in the SBA metadata */ st_ivas->nchan_ism = 2 * st_ivas->bit_stream[ivas_total_brate / FRAMES_PER_SEC - 1] + st_ivas->bit_stream[ivas_total_brate / FRAMES_PER_SEC - 2] + 1; - if ( ivas_total_brate < IVAS_24k4 || ivas_total_brate >= IVAS_256k ) - { - /* read Ambisonic (SBA) planar flag */ - st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read]; - num_bits_read += SBA_PLANAR_BITS; - } + /* read Ambisonic (SBA) planar flag */ + st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read]; + num_bits_read += SBA_PLANAR_BITS; + /* read Ambisonic (SBA) order (0 for signaling OSBA format at low bitrates)*/ st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; num_bits_read += SBA_ORDER_BITS; - /* read Ambisonic (SBA) order */ - if ( ivas_total_brate < IVAS_256k ) + /* read the real Ambisonic order when the above bits are used to signal OSBA format */ + if ( ivas_total_brate < IVAS_24k4 ) { - st_ivas->sba_order = 3; + st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; + st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + num_bits_read += SBA_ORDER_BITS; } - if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -506,11 +302,15 @@ ivas_error ivas_dec_setup( /*correct number of CPEs for discrete ISM coding*/ if ( st_ivas->ini_frame > 0 && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; + { + int16_t n; + + n = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( n + 1 ) >> 1; + } } } - - if ( ivas_total_brate >= IVAS_256k ) + if ( ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ) == ISM_SBA_MODE_DISC ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; } @@ -533,17 +333,10 @@ ivas_error ivas_dec_setup( num_bits_read += MC_LS_SETUP_BITS; /* select MC format mode; reconfigure the MC format decoder */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_mc_dec_config( st_ivas, idx, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) { return error; } -#else - if ( ( error = ivas_mc_dec_config( st_ivas, idx, nSamplesRendered, data ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif } /*-------------------------------------------------------------------* @@ -607,6 +400,12 @@ ivas_error ivas_dec_setup( break; } + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + st_ivas->hDecoderConfig->output_config = ivas_set_output_config_from_sba_order( st_ivas->sba_order ); + st_ivas->hDecoderConfig->nchan_out = audioCfg2channels( st_ivas->hDecoderConfig->output_config ); + } + if ( st_ivas->ini_frame > 0 && st_ivas->ivas_format == SBA_FORMAT ) { int16_t nchan_transport_old, nchan_transport; @@ -625,11 +424,7 @@ ivas_error ivas_dec_setup( st_ivas->hDecoderConfig->ivas_total_brate = IVAS_24k4; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -675,11 +470,7 @@ ivas_error ivas_dec_setup( last_ism_mode = st_ivas->ism_mode; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -704,20 +495,6 @@ ivas_error ivas_dec_setup( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*-----------------------------------------------------------------* - * reconfig split rendering as renderer might change after bitrate switching - *-----------------------------------------------------------------*/ - - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#endif - /*----------------------------------------------------------------* * Reset bitstream pointers *----------------------------------------------------------------*/ @@ -801,7 +578,6 @@ static ivas_error ivas_read_format( st_ivas->ivas_format = MASA_ISM_FORMAT; } } - ( *num_bits_read )++; } break; @@ -884,6 +660,14 @@ static ivas_error ivas_read_format( if ( st_ivas->ivas_format == SBA_FORMAT ) { + /* read Ambisonic (SBA) planar flag */ + st_ivas->sba_planar = st_ivas->bit_stream[*num_bits_read]; + *num_bits_read += SBA_PLANAR_BITS; + + /* read Ambisonic (SBA) order */ + st_ivas->sba_order = st_ivas->bit_stream[*num_bits_read + 1]; + st_ivas->sba_order += 2 * st_ivas->bit_stream[*num_bits_read]; + *num_bits_read += SBA_ORDER_BITS; if ( st_ivas->sba_analysis_order == 0 ) { st_ivas->sba_analysis_order = SBA_FOA_ORDER; @@ -1091,11 +875,8 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Binaural Renderer configuration handle *--------------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) ) { if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) { @@ -1127,7 +908,7 @@ ivas_error ivas_init_decoder( int16_t numCldfbAnalyses, numCldfbSyntheses; int16_t granularity, n_channels_transport_jbm; int32_t output_Fs, ivas_total_brate; - int32_t binauralization_delay_ns; + int32_t delay_ns; AUDIO_CONFIG output_config; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -1149,7 +930,15 @@ ivas_error ivas_init_decoder( if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { - if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + hDecoderConfig->nchan_out = CPE_CHANNELS; + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + hDecoderConfig->nchan_out = audioCfg2channels( st_ivas->transport_config ); + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { hDecoderConfig->nchan_out = audioCfg2channels( IVAS_AUDIO_CONFIG_HOA3 ); hDecoderConfig->nchan_out += st_ivas->nchan_ism; @@ -1172,7 +961,15 @@ ivas_error ivas_init_decoder( st_ivas->intern_config = output_config; - ivas_output_init( &( st_ivas->hOutSetup ), output_config ); + if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->ivas_format == MC_FORMAT ) + { + ivas_output_init( &( st_ivas->hOutSetup ), st_ivas->transport_config ); + st_ivas->intern_config = st_ivas->transport_config; + } + else + { + ivas_output_init( &( st_ivas->hOutSetup ), output_config ); + } if ( st_ivas->ivas_format == SBA_ISM_FORMAT && output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { @@ -1250,24 +1047,6 @@ ivas_error ivas_init_decoder( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*-----------------------------------------------------------------* - * Initialize binuaral split rendering - *-----------------------------------------------------------------*/ - - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses = 1; - } -#endif - /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ @@ -1336,11 +1115,7 @@ ivas_error ivas_init_decoder( } } -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nSCE, element_brate_tmp ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1591,7 +1366,12 @@ ivas_error ivas_init_decoder( if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; + { + int16_t n_all; + + n_all = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( n_all + 1 ) >> 1; + } st_ivas->element_mode_init = IVAS_CPE_MDCT; } @@ -1674,7 +1454,6 @@ ivas_error ivas_init_decoder( reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] ); -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) @@ -1684,14 +1463,11 @@ ivas_error ivas_init_decoder( } else { -#endif if ( ( error = ivas_ism_metadata_dec_create( st_ivas, 1, NULL ) ) != IVAS_ERR_OK ) { return error; } -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE } -#endif } else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { @@ -2058,13 +1834,8 @@ ivas_error ivas_init_decoder( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, - st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, - st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) -#endif + st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) { return error; } @@ -2192,40 +1963,6 @@ ivas_error ivas_init_decoder( } } - /*-----------------------------------------------------------------* - * LFE handles for rendering after rendering to adjust LFE delay to binaural filter delay - *-----------------------------------------------------------------*/ - - if ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) - { - binauralization_delay_ns = st_ivas->binaural_latency_ns; - if ( st_ivas->hBinRenderer != NULL ) - { - if ( st_ivas->hBinRenderer->render_lfe ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif - { - /* Account for filterbank delay */ - binauralization_delay_ns += IVAS_FB_DEC_DELAY_NS; - } - } - else - { - binauralization_delay_ns = 0; - } - } - - if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, output_Fs, binauralization_delay_ns ) ) != IVAS_ERR_OK ) - { - return error; - } - - set_zero( st_ivas->hLFE->prevsynth_buf, LFE_PLC_BUFLEN ); - set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k ); - } - /*-----------------------------------------------------------------* * CLDFB handles for rendering *-----------------------------------------------------------------*/ @@ -2262,6 +1999,45 @@ ivas_error ivas_init_decoder( ivas_spar_get_cldfb_gains( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); } + /*-----------------------------------------------------------------* + * LFE handles for rendering after rendering to adjust LFE delay to filter delay + *-----------------------------------------------------------------*/ + + if ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + delay_ns = st_ivas->binaural_latency_ns; + if ( st_ivas->hBinRenderer != NULL ) + { + if ( st_ivas->hBinRenderer->render_lfe ) + { + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + /* Account for filterbank delay */ + delay_ns += IVAS_FB_DEC_DELAY_NS; + } + } + else + { + delay_ns = 0; + } + } + else + { + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( st_ivas->cldfbSynDec[0] != NULL ) ) + { + delay_ns += IVAS_FB_DEC_DELAY_NS; + } + } + + if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, output_Fs, delay_ns ) ) != IVAS_ERR_OK ) + { + return error; + } + + set_zero( st_ivas->hLFE->prevsynth_buf, LFE_PLC_BUFLEN ); + set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k ); + } + /*-----------------------------------------------------------------* * Allocate and initialize limiter struct *-----------------------------------------------------------------*/ @@ -2296,7 +2072,11 @@ ivas_error ivas_init_decoder( } } +#ifdef FIX_1099_JBM_MD_HANDLE_ALLOC + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->Opt_tsm ) +#else if ( st_ivas->hJbmMetadata == NULL && st_ivas->hDecoderConfig->Opt_tsm ) +#endif { if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -2529,14 +2309,10 @@ void ivas_initialize_handles_dec( /* rendering handles */ st_ivas->hBinRenderer = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) { st_ivas->hDiracDecBin[i] = NULL; } -#else - st_ivas->hDiracDecBin = NULL; -#endif st_ivas->hDirACRend = NULL; st_ivas->hSpatParamRendCom = NULL; st_ivas->hLsSetUpConversion = NULL; @@ -2562,13 +2338,11 @@ void ivas_initialize_handles_dec( st_ivas->hExtOrientationData = NULL; st_ivas->hCombinedOrientationData = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT - st_ivas->hSplitBinRend.hMultiBinCldfbData = NULL; - st_ivas->hSplitBinRend.hSplitRendBits = NULL; - st_ivas->hSplitBinRend.hCldfbDataOut = NULL; - st_ivas->hSplitBinRend.numTdSamplesPerChannelCached = 0; - ivas_init_split_rend_handles( &st_ivas->hSplitBinRend.splitrend ); -#endif + st_ivas->hSplitBinRend = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + st_ivas->hTdRendHandles[i] = NULL; + } /* JBM handles */ st_ivas->hTcBuffer = NULL; @@ -2706,31 +2480,21 @@ void ivas_destroy_dec( /* Fastconv binaural renderer handle */ ivas_binRenderer_close( &st_ivas->hBinRenderer ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - /* Split binaural renderer handle */ - ivas_split_renderer_close( &st_ivas->hSplitBinRend.splitrend ); - - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + /* TD binaural renderer handles */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - free( st_ivas->hSplitBinRend.hCldfbDataOut ); - st_ivas->hSplitBinRend.hCldfbDataOut = NULL; + if ( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); + } } -#endif /* Parametric binaural renderer handle */ -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); -#else - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); -#endif /* Crend handle */ - -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); -#endif + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); /* Reverb handle */ ivas_reverb_close( &st_ivas->hReverb ); @@ -2881,11 +2645,8 @@ void ivas_init_dec_get_num_cldfb_instances( *numCldfbAnalyses = st_ivas->nchan_transport + 1; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->useTdDecorr ) -#else - if ( st_ivas->hDiracDecBin->useTdDecorr ) -#endif { *numCldfbAnalyses += 2; } @@ -3090,57 +2851,28 @@ static ivas_error doSanityChecks_IVAS( /* Verify stereo output configuration */ if ( st_ivas->ivas_format == STEREO_FORMAT ) { - if ( output_config != IVAS_AUDIO_CONFIG_MONO && output_config != IVAS_AUDIO_CONFIG_STEREO && output_config != IVAS_AUDIO_CONFIG_5_1 && output_config != IVAS_AUDIO_CONFIG_7_1 && output_config != IVAS_AUDIO_CONFIG_5_1_2 && output_config != IVAS_AUDIO_CONFIG_5_1_4 && output_config != IVAS_AUDIO_CONFIG_7_1_4 && output_config != IVAS_AUDIO_CONFIG_LS_CUSTOM ) + if ( output_config != IVAS_AUDIO_CONFIG_MONO && output_config != IVAS_AUDIO_CONFIG_STEREO && output_config != IVAS_AUDIO_CONFIG_5_1 && output_config != IVAS_AUDIO_CONFIG_7_1 && output_config != IVAS_AUDIO_CONFIG_5_1_2 && output_config != IVAS_AUDIO_CONFIG_5_1_4 && output_config != IVAS_AUDIO_CONFIG_7_1_4 && output_config != IVAS_AUDIO_CONFIG_LS_CUSTOM && output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Wrong output configuration specified for Stereo!" ); } } - else if ( st_ivas->ivas_format == ISM_FORMAT ) - { - /* Verify ISM output configuration */ - if ( output_config == IVAS_AUDIO_CONFIG_INVALID ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for ISM" ); - } - } - else if ( st_ivas->ivas_format == SBA_FORMAT ) - { - /* Verify SBA output coniguration */ - if ( output_config == IVAS_AUDIO_CONFIG_INVALID ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for SBA" ); - } - } - else if ( st_ivas->ivas_format == MASA_FORMAT ) + /* Verify output configuration for other formats */ + else { if ( output_config == IVAS_AUDIO_CONFIG_INVALID ) { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for MASA!" ); - } - } - else if ( st_ivas->ivas_format == MC_FORMAT ) - { - /* Verify MC output configuration */ - if ( output_config == IVAS_AUDIO_CONFIG_INVALID || output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for Multi-channel" ); + return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified!" ); } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && output_Fs != 48000 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); } -#endif if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { - if ( !( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) ) + if ( !( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" ); } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index ef13d2463db77908b7b861b266ccc3e96dd50ffd..4f5dc179dd06a36d4d677c3c7ada2108629a6d7a 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -47,16 +47,12 @@ *-------------------------------------------------------------------------*/ static ivas_error ivas_ism_bitrate_switching_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t nchan_transport_old, /* i : last number of transport channels */ - const ISM_MODE last_ism_mode, /* i : last ISM mode */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t nchan_transport_old, /* i : last number of transport channels */ + const ISM_MODE last_ism_mode, /* i : last ISM mode */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { ivas_error error; @@ -146,11 +142,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -181,18 +173,10 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* Deallocate the ParamISM struct */ ivas_param_ism_dec_close( &( st_ivas->hParamIsmDec ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config ); - if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { /* close the parametric binaural renderer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); -#else - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); -#endif /* Open the TD Binaural renderer */ if ( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) { @@ -223,18 +207,10 @@ static ivas_error ivas_ism_bitrate_switching_dec( if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { /* close the parametric binaural renderer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); -#else - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); -#endif /* Open Crend Binaural renderer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) -#endif + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) { return error; } @@ -252,11 +228,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } - if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { /* open the parametric binaural renderer */ if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) @@ -270,25 +242,12 @@ static ivas_error ivas_ism_bitrate_switching_dec( } /* Close the TD Binaural renderer */ -#ifdef NONBE_FIX_1045_ISM_BITRATE_SWITCHING ivas_td_binaural_close( &st_ivas->hBinRendererTd ); if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { ivas_reverb_close( &st_ivas->hReverb ); } -#else - if ( st_ivas->hBinRendererTd->HrFiltSet_p->ModelParams.modelROM == TRUE ) - { - ivas_td_binaural_close( &st_ivas->hBinRendererTd ); - st_ivas->hHrtfTD = NULL; - - if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - ivas_reverb_close( &st_ivas->hReverb ); - } - } -#endif } else { @@ -310,11 +269,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( } /* close the crend binaural renderer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); -#endif + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); } } @@ -393,15 +348,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ - uint16_t *nSamplesRendered, /* o : number of samples flushed when the renderer granularity changes */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ + uint16_t *nSamplesRendered, /* o : number of samples flushed when the renderer granularity changes */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { int32_t ivas_total_brate; @@ -437,17 +388,11 @@ ivas_error ivas_ism_dec_config( if ( st_ivas->ini_active_frame != 0 ) { /* ISM bit-rate switching */ + if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { - if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) + if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, -#ifdef SPLIT_REND_WITH_HEAD_ROT - pcm_resolution, -#endif - data ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } } @@ -467,11 +412,7 @@ ivas_error ivas_ism_dec_config( /* ISM mode switching */ if ( st_ivas->ism_mode != last_ism_mode ) { - if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, -#ifdef SPLIT_REND_WITH_HEAD_ROT - pcm_resolution, -#endif - data ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index bd7a906e20dcc178586abbb3933b3b787616224d..4525b21e106dc7f73d76df7ebe196a1f39e66897 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -642,7 +642,6 @@ ivas_error ivas_ism_metadata_dec( return IVAS_ERR_OK; } -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE /*-------------------------------------------------------------------* * ivas_ism_reset_metadata_handle_dec() @@ -675,7 +674,6 @@ void ivas_ism_reset_metadata_handle_dec( return; } -#endif /*------------------------------------------------------------------------- * ivas_ism_metadata_dec_create() @@ -684,61 +682,28 @@ void ivas_ism_reset_metadata_handle_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_metadata_dec_create( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE - const int16_t n_ISms, /* i : number of separately coded objects */ -#else - const int16_t n_ISms, /* i : number of objects */ -#endif + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_ISms, /* i : number of separately coded objects */ int32_t element_brate_tmp[] /* o : element bitrate per object */ ) { int16_t ch; ivas_error error; -/* allocate ISM metadata handles */ -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE + /* allocate ISM metadata handles */ for ( ch = 0; ch < n_ISms; ch++ ) -#else - for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) -#endif { -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE if ( st_ivas->hIsmMetaData[ch] == NULL ) /* note: the handle can be allocated in OMASA bitrate switching from ISM_MASA_MODE_xxx_ONE_OBJ to ISM_MASA_MODE_DISC mode for 'ch==0' */ { -#endif if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) ); } -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE } -#endif -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[ch] ); -#else - st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; - st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; - st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); - st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; - st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); - st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */ - - st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; - st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; - st_ivas->hIsmMetaData[ch]->last_azimuth = 0; - st_ivas->hIsmMetaData[ch]->last_elevation = 0; - - st_ivas->hIsmMetaData[ch]->ism_imp = -1; - st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; - st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; - - ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); -#endif } -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE /* sanity freeing - it can happen only in reconfiguration when a smaller number of handles than before is requested */ for ( ; ch < MAX_NUM_OBJECTS; ch++ ) { @@ -748,7 +713,6 @@ ivas_error ivas_ism_metadata_dec_create( st_ivas->hIsmMetaData[ch] = NULL; } } -#endif if ( element_brate_tmp != NULL ) { diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 2e3720c9493acc638d2a74fa3dddd735eaf2e003..01efe5669d2d061f105332baa8df2039a0d2e523 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -350,11 +350,7 @@ static ivas_error ivas_param_ism_rendering_init( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) -#else - if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) -#endif { /* computation of proto matrix */ ivas_ism_get_proto_matrix( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix ); @@ -507,13 +503,8 @@ ivas_error ivas_param_ism_dec_open( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) -#else - if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || - output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) ) -#endif { /* Initialize efap handle */ if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), hOutSetup.ls_azimuth, hOutSetup.ls_elevation, hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) @@ -530,11 +521,7 @@ ivas_error ivas_param_ism_dec_open( hSpatParamRendCom->dirac_bs_md_write_idx = 0; hSpatParamRendCom->dirac_read_idx = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif { if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 1 ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index b890dd98e5c64f778d5a9a2e0b3f7b146210b313..11b8c5a2029854c41c3ac70ebe1cda90a000f23d 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -66,7 +66,10 @@ ivas_error ivas_ism_renderer_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer\n" ) ); } - if ( st_ivas->hIntSetup.is_loudspeaker_setup && st_ivas->hIntSetup.ls_azimuth != NULL && st_ivas->hIntSetup.ls_elevation != NULL && st_ivas->hEFAPdata == NULL ) + if ( st_ivas->hIntSetup.is_loudspeaker_setup && + st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_STEREO && + st_ivas->hIntSetup.ls_azimuth != NULL && st_ivas->hIntSetup.ls_elevation != NULL && + st_ivas->hEFAPdata == NULL ) { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index ffb018c06d4f81d650214947b9fcb251a3f60d9a..27a64e35d6f52a0084e6d488a758086922a7aa58 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -681,7 +681,7 @@ ivas_error ivas_jbm_dec_tc( /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */ if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || - output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) + output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) || output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL ); } @@ -858,19 +858,13 @@ void ivas_jbm_dec_feed_tc_to_renderer( /* delay the objects here for all renderers where it is needed */ if ( -#ifdef SPLIT_REND_WITH_HEAD_ROT ( -#endif st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || - st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL -#ifdef SPLIT_REND_WITH_HEAD_ROT - ) && - ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif - ) + st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) && + ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { for ( n = 0; n < st_ivas->nchan_ism; n++ ) { @@ -939,7 +933,10 @@ void ivas_jbm_dec_feed_tc_to_renderer( { v_multc( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], OMASA_TDREND_MATCHING_GAIN, st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); } - delay_signal( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + delay_signal( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + } } } } @@ -976,16 +973,12 @@ void ivas_jbm_dec_feed_tc_to_renderer( *--------------------------------------------------------------------------*/ ivas_error ivas_jbm_dec_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesAsked, /* i : number of samples wanted */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const uint16_t nSamplesAsked, /* i : number of samples wanted */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { int16_t n, nchan_out; @@ -998,9 +991,7 @@ ivas_error ivas_jbm_dec_render( float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; float *p_tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t nchan_out_syn_output; -#endif push_wmops( "ivas_dec_render" ); /*----------------------------------------------------------------* @@ -1119,7 +1110,6 @@ ivas_error ivas_jbm_dec_render( /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) @@ -1129,23 +1119,16 @@ ivas_error ivas_jbm_dec_render( } else { -#endif if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { -#if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1322,10 +1305,9 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -1333,25 +1315,15 @@ ivas_error ivas_jbm_dec_render( } else { -#endif - -#if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, - &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) - -#endif { return error; } ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -1364,7 +1336,6 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) @@ -1374,16 +1345,13 @@ ivas_error ivas_jbm_dec_render( } else { -#endif if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) @@ -1394,10 +1362,8 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*handled in CLDFB domain already*/ + /* handled in CLDFB domain already */ if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif { ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); } @@ -1487,18 +1453,16 @@ ivas_error ivas_jbm_dec_render( st_ivas->hTcBuffer->n_samples_discard = 0; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; } else { nchan_out_syn_output = nchan_out; } - if ( st_ivas->hDecoderConfig->Opt_Limiter ) -#endif + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) { if ( st_ivas->ivas_format != MONO_FORMAT ) { @@ -1508,21 +1472,14 @@ ivas_error ivas_jbm_dec_render( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT switch ( pcm_resolution ) { case PCM_INT16: -#endif #ifdef DEBUGGING st_ivas->noClipping += #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_syn_output( p_output, *nSamplesRendered, nchan_out_syn_output, (int16_t *) data ); -#else - ivas_syn_output( p_output, *nSamplesRendered, nchan_out, data ); -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT break; case PCM_FLOAT32: ivas_syn_output_f( p_output, *nSamplesRendered, nchan_out_syn_output, (float *) data ); @@ -1531,7 +1488,6 @@ ivas_error ivas_jbm_dec_render( error = IVAS_ERR_UNKNOWN; break; } -#endif *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available; @@ -1555,12 +1511,8 @@ ivas_error ivas_jbm_dec_flush_renderer( const MC_MODE mc_mode_old, /* i : old MC mode */ const ISM_MODE ism_mode_old, /* i : old ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ - void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ ) { ivas_error error; @@ -1637,13 +1589,8 @@ ivas_error ivas_jbm_dec_flush_renderer( ivas_ism_render_sf( st_ivas, renderer_type_old, p_output, hTcBuffer->n_samples_granularity ); -#if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, - NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1658,14 +1605,26 @@ ivas_error ivas_jbm_dec_flush_renderer( { if ( mc_mode_old == MC_MODE_MCT ) { +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT + int16_t crendInPlaceRotation = FALSE; + + if ( st_ivas->transport_config != intern_config_old && ( intern_config_old == IVAS_AUDIO_CONFIG_FOA || intern_config_old == IVAS_AUDIO_CONFIG_HOA2 || intern_config_old == IVAS_AUDIO_CONFIG_HOA3 ) ) + { + if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) < ( hIntSetupOld->nchan_out_woLFE + hIntSetupOld->num_lfe ) ) + { + crendInPlaceRotation = TRUE; + ivas_mc2sba( st_ivas->hTransSetup, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, hIntSetupOld->ambisonics_order, GAIN_LFE ); + } + } +#endif if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV || renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { -#if defined SPLIT_REND_WITH_HEAD_ROT +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, - hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) + hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : st_ivas->hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, - hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) #endif { return error; @@ -1776,9 +1735,7 @@ ivas_error ivas_jbm_dec_flush_renderer( *nSamplesRendered = n_samples_to_render; /* Only write out the valid data*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hDecoderConfig->Opt_Limiter ) -#endif + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) { if ( st_ivas->ivas_format != MONO_FORMAT ) { @@ -1788,21 +1745,13 @@ ivas_error ivas_jbm_dec_flush_renderer( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT switch ( pcm_resolution ) { case PCM_INT16: -#endif #ifdef DEBUGGING st_ivas->noClipping += #endif - ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, -#ifdef SPLIT_REND_WITH_HEAD_ROT - (int16_t *) -#endif - data ); - -#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) data ); break; case PCM_FLOAT32: ivas_syn_output_f( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (float *) data ); @@ -1811,7 +1760,6 @@ ivas_error ivas_jbm_dec_flush_renderer( error = IVAS_ERR_UNKNOWN; break; } -#endif return IVAS_ERR_OK; } @@ -2380,6 +2328,7 @@ ivas_error ivas_jbm_dec_tc_buffer_open( { if ( st_ivas->hDecoderConfig->Opt_tsm ) { + /* note: the maximum buffer length is for OSBA DISC mode with ISMs -> 15*(1920+239)=32385 samples */ if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c index 83b196190730ff0f18693f872607393e88b75f47..28469f47d1e4978f2eb8f6f63ad3d60b2e2e5415 100644 --- a/lib_dec/ivas_lfe_dec.c +++ b/lib_dec/ivas_lfe_dec.c @@ -252,6 +252,26 @@ static int16_t ivas_lfe_dec_dequant( } +/*------------------------------------------------------------------------- + * ivas_create_lfe_lpf_dec() + * + * Create, allocate and initialize IVAS decoder LFE low pass filter state handle + *-------------------------------------------------------------------------*/ + +static void ivas_create_lfe_lpf_dec( + ivas_filters_process_state_t *hLfeLpf, /* o : LFE LPF handle */ + const int32_t input_Fs /* i : input sampling rate */ +) +{ + const float *filt_coeff; + + ivas_lfe_lpf_select_filt_coeff( input_Fs, IVAS_FILTER_ORDER_4, &filt_coeff ); + ivas_filters_init( hLfeLpf, filt_coeff, IVAS_FILTER_ORDER_4 ); + + return; +} + + /*-----------------------------------------------------------------------------------------* * Function ivas_lfe_dec() * @@ -350,9 +370,9 @@ void ivas_lfe_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_create_lfe_dec( - LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ - const int32_t output_Fs, /* i : output sampling rate */ - const int32_t binauralization_delay_ns /* i : additional LFE delay to sync with binaural renderer */ + LFE_DEC_HANDLE *hLFE_out, /* o : IVAS LFE decoder structure */ + const int32_t output_Fs, /* i : output sampling rate */ + const int32_t delay_ns /* i : additional LFE delay to sync other channel outputs */ ) { float low_pass_delay_dec_out, block_offset_s; @@ -403,6 +423,13 @@ ivas_error ivas_create_lfe_dec( block_offset_s = BLOCK_OFFSET_MS * 0.001f; filt_order = 0; low_pass_delay_dec_out = 0; + if ( ( delay_ns / 1000000000.f ) > ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] ) + { + filt_order = 4; + low_pass_delay_dec_out = ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000.f; + ivas_create_lfe_lpf_dec( &( hLFE->filter_state ), output_Fs ); + } + hLFE->filter_state.order = filt_order; hLFE->lfe_block_delay_s = hLFE->lfe_block_delay_s + low_pass_delay_dec_out; hLFE->lfe_prior_buf_len = NS2SA( output_Fs, IVAS_LFE_FADE_NS ); @@ -411,7 +438,7 @@ ivas_error ivas_create_lfe_dec( lfe_addl_delay_s = block_offset_s - hLFE->lfe_block_delay_s; lfe_addl_delay_s = max( 0.0f, lfe_addl_delay_s ); - add_delay_sa = (int16_t) roundf( (float) binauralization_delay_ns * output_Fs / 1000000000.f ); + add_delay_sa = (int16_t) roundf( (float) delay_ns * output_Fs / 1000000000.f ); hLFE->lfe_addl_delay = (int16_t) ( lfe_addl_delay_s * output_Fs ) + add_delay_sa; hLFE->lfe_block_delay_s += lfe_addl_delay_s + add_delay_sa / output_Fs; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 3d05c01ad4a00b725269826b5c295d027ee3eb99..79f3c046a1578e0748d7c50a6c800a28bfe33340 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -151,73 +151,92 @@ ivas_error ivas_masa_decode( { if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) { - if ( ivas_format != MASA_ISM_FORMAT ) + if ( ivas_format == MASA_FORMAT ) { - /* number of transport channels is always 2 for MASA_ISM format */ - /* the number of MASA transport channels was read in ivas_dec_setup() */ - st->next_bit_pos -= MASA_TRANSP_BITS; - *nb_bits_read += MASA_TRANSP_BITS; + /* re-read the number of objects, needed in case of bad frame */ + st_ivas->nchan_ism = 5 - ( st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 3] + 2 * st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 2] ); } - - if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode != ISM_MODE_NONE ) + if ( ivas_format == MASA_FORMAT && st_ivas->nchan_ism != 5 ) { - /* the number of objects was read */ - st->next_bit_pos -= NO_BITS_MASA_ISM_NO_OBJ; - *nb_bits_read += NO_BITS_MASA_ISM_NO_OBJ; - - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + /* there was OMASA in the input */ + hMasa->config.input_ivas_format = MASA_ISM_FORMAT; + if ( st_ivas->nchan_ism < 3 ) { - /* read index of separated object */ - /* nchan_ism should be > 1*/ + /* was read in ivas_init_dec() to distinguish between 1 and 2 objects */ + if ( st_ivas->bit_stream[( ivas_total_brate / FRAMES_PER_SEC ) - 1] == 0 ) + { + st_ivas->nchan_ism = 1; + } + st->next_bit_pos -= MASA_TRANSP_BITS; + *nb_bits_read += MASA_TRANSP_BITS; + + /* the two reserved bits were already read in ivas_init_dec()*/ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read += MASA_HEADER_BITS; + /* read number of directions */ byteBuffer = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits_read )++; - st_ivas->hMasaIsmData->idx_separated_ism = 2 * byteBuffer + st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits_read )++; + hMasa->config.numberOfDirections = (uint8_t) ( byteBuffer + 1 ); } else { - st_ivas->hMasaIsmData->idx_separated_ism = -1; - } + /* if there are 3 or 4 objects the number of transport channels bit is given to MASA format + and used to read number of directions*/ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read )++; + hMasa->config.numberOfDirections = (uint8_t) ( byteBuffer + 1 ); - /* read ISM importance flag (one per object) */ - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + /* the two reserved bits were already read in ivas_init_dec()*/ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + *nb_bits_read += MASA_HEADER_BITS; + } + } + else + { + if ( ivas_format != MASA_ISM_FORMAT ) { - ism_imp = 0; - for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) - { - byteBuffer = st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits_read )++; - ism_imp = ( ism_imp << 1 ) + byteBuffer; - } - st_ivas->hIsmMetaData[0]->ism_imp = ism_imp; + /* number of transport channels is always 2 for MASA_ISM format */ + /* the number of MASA transport channels was read in ivas_dec_setup() */ + st->next_bit_pos -= MASA_TRANSP_BITS; + *nb_bits_read += MASA_TRANSP_BITS; } - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode != ISM_MODE_NONE ) { - ism_imp = 0; - for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) + /* the number of objects was read */ + st->next_bit_pos -= NO_BITS_MASA_ISM_NO_OBJ; + *nb_bits_read += NO_BITS_MASA_ISM_NO_OBJ; + + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { + /* read index of separated object */ + /* nchan_ism should be > 1*/ byteBuffer = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits_read )++; - ism_imp = ( ism_imp << 1 ) + byteBuffer; + st_ivas->hMasaIsmData->idx_separated_ism = 2 * byteBuffer + st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read )++; + } + else + { + st_ivas->hMasaIsmData->idx_separated_ism = -1; } - st_ivas->hIsmMetaData[0]->ism_imp = ism_imp; - /* reset */ - st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0; - st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0; - if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META ) + /* read ISM importance flag (one per object) */ + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - /* read flags */ - st_ivas->hIsmMetaData[0]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits_read ) += ISM_METADATA_MD_FLAG_BITS; - st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits_read ) += ISM_METADATA_INACTIVE_FLAG_BITS; + ism_imp = 0; + for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) + { + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read )++; + ism_imp = ( ism_imp << 1 ) + byteBuffer; + } + st_ivas->hIsmMetaData[0]->ism_imp = ism_imp; } - } - else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) - { - for ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + + if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) { ism_imp = 0; for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) @@ -226,53 +245,72 @@ ivas_error ivas_masa_decode( ( *nb_bits_read )++; ism_imp = ( ism_imp << 1 ) + byteBuffer; } - st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp; + st_ivas->hIsmMetaData[0]->ism_imp = ism_imp; /* reset */ - st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; - st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; - if ( st_ivas->hIsmMetaData[ch]->ism_imp == ISM_NO_META ) + st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0; + st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0; + if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META ) { /* read flags */ - st_ivas->hIsmMetaData[ch]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--]; + st_ivas->hIsmMetaData[0]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits_read ) += ISM_METADATA_MD_FLAG_BITS; - st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--]; + st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits_read ) += ISM_METADATA_INACTIVE_FLAG_BITS; } } - st_ivas->flag_omasa_brate = 0; - if ( st_ivas->nchan_ism >= 3 && ivas_total_brate == IVAS_128k ) + else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { - st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits_read ) += 1; + for ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + { + ism_imp = 0; + for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ ) + { + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read )++; + ism_imp = ( ism_imp << 1 ) + byteBuffer; + } + st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp; + + /* reset */ + st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; + st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; + if ( st_ivas->hIsmMetaData[ch]->ism_imp == ISM_NO_META ) + { + /* read flags */ + st_ivas->hIsmMetaData[ch]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read ) += ISM_METADATA_MD_FLAG_BITS; + st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read ) += ISM_METADATA_INACTIVE_FLAG_BITS; + } + } + st_ivas->flag_omasa_brate = 0; + if ( st_ivas->nchan_ism >= 3 && ivas_total_brate == IVAS_128k ) + { + st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read ) += 1; + } } } - } - /* read 2 bits: - '00' - MASA format at the encoder - '01' - MASA_ISM_FORMAT at the encoder, with 1 object - '10' - MASA_ISM_FORMAT at the encoder, with 2 objects - '11' - MASA_ISM_FORMAT at the encoder, with 3 or 4 objects - reading if 3 or 4 object is performed later - */ - byteBuffer = st->bit_stream[( st->next_bit_pos )--]; - byteBuffer = byteBuffer + 2 * st->bit_stream[( st->next_bit_pos )--]; + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + byteBuffer = byteBuffer + 2 * st->bit_stream[( st->next_bit_pos )--]; - if ( byteBuffer == 0 && ivas_format == MASA_FORMAT ) - { - hMasa->config.input_ivas_format = MASA_FORMAT; - } - else - { - hMasa->config.input_ivas_format = MASA_ISM_FORMAT; - } - *nb_bits_read += MASA_HEADER_BITS; + if ( byteBuffer == 0 && ivas_format == MASA_FORMAT ) + { + hMasa->config.input_ivas_format = MASA_FORMAT; + } + else + { + hMasa->config.input_ivas_format = MASA_ISM_FORMAT; + } + *nb_bits_read += MASA_HEADER_BITS; - /* read number of directions */ - byteBuffer = st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits_read )++; - hMasa->config.numberOfDirections = (uint8_t) ( byteBuffer + 1 ); + /* read number of directions */ + byteBuffer = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits_read )++; + hMasa->config.numberOfDirections = (uint8_t) ( byteBuffer + 1 ); + } } else { @@ -397,7 +435,7 @@ ivas_error ivas_masa_decode( hMasa->config.coherencePresent = !hQMetaData->all_coherence_zero; - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL && ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) ) { index_16bits( hQMetaData, hMasa->data.sph_grid16 ); } @@ -617,7 +655,7 @@ ivas_error ivas_masa_dec_open( hMasa->config.joinedSubframes = FALSE; /* Create spherical grid only for external output */ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL && ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) ) { if ( ( hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL ) { @@ -1048,6 +1086,7 @@ static ivas_error init_lfe_synth_data( ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 || output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || + output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_FOA || output_config == IVAS_AUDIO_CONFIG_HOA2 || output_config == IVAS_AUDIO_CONFIG_HOA3 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) ) @@ -1262,14 +1301,10 @@ static int16_t decode_lfe_to_total_energy_ratio( *-------------------------------------------------------------------*/ ivas_error ivas_masa_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { int16_t n, tmp, num_bits; @@ -1279,9 +1314,7 @@ ivas_error ivas_masa_dec_reconfigure( int32_t ivas_total_brate, last_ivas_total_brate; int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; ivas_error error; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif int32_t ism_total_brate; error = IVAS_ERR_OK; @@ -1301,13 +1334,8 @@ ivas_error ivas_masa_dec_reconfigure( /* renderer might have changed, reselect */ ivas_renderer_select( st_ivas ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend == NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] == NULL ) ) -#else - if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend == NULL ) || - ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin == NULL ) ) -#endif { /* init a new DirAC dec */ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK ) @@ -1320,11 +1348,7 @@ ivas_error ivas_masa_dec_reconfigure( if ( st_ivas->hDirAC != NULL ) { /* close all unnecessary parametric decoding and rendering */ -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); -#else - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); -#endif ivas_dirac_rend_close( &( st_ivas->hDirACRend ) ); ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) ); ivas_dirac_dec_close( &( st_ivas->hDirAC ) ); @@ -1348,11 +1372,7 @@ ivas_error ivas_masa_dec_reconfigure( sts[0]->bit_stream = bit_stream + num_bits; num_bits += (int16_t) ( st_ivas->hSCE[sce_id]->element_brate / FRAMES_PER_SEC ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) -#else - if ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) -#endif { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1378,11 +1398,7 @@ ivas_error ivas_masa_dec_reconfigure( { st_ivas->hCPE[cpe_id]->nchan_out = 1; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) ) -#else - if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) ) -#endif { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1394,11 +1410,7 @@ ivas_error ivas_masa_dec_reconfigure( { st_ivas->hCPE[cpe_id]->nchan_out = CPE_CHANNELS; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) ) -#else - if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) ) -#endif { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1408,22 +1420,13 @@ ivas_error ivas_masa_dec_reconfigure( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { if ( st_ivas->hDiracDecBin[pos_idx] != NULL ) { -#else - if ( st_ivas->hDiracDecBin != NULL ) - { -#endif /* regularization factor is bitrate-dependent */ -#ifdef SPLIT_REND_WITH_HEAD_ROT st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); } -#else - st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif } if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */ @@ -1431,17 +1434,10 @@ ivas_error ivas_masa_dec_reconfigure( /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] != NULL ) -#else - if ( st_ivas->hDiracDecBin != NULL ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1519,11 +1515,7 @@ ivas_error ivas_masa_dec_reconfigure( { if ( n_samples_granularity < st_ivas->hTcBuffer->n_samples_granularity ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, n_samples_granularity, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, MC_MODE_NONE, ISM_MASA_MODE_DISC, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, n_samples_granularity, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, MC_MODE_NONE, ISM_MASA_MODE_DISC, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1610,11 +1602,7 @@ void ivas_spar_param_to_masa_param_mapping( hSpatParamRendCom = st_ivas->hSpatParamRendCom; hSpatParamRendCom->numParametricDirections = 1; hSpatParamRendCom->numSimultaneousDirections = 1; -#ifdef SPLIT_REND_WITH_HEAD_ROT hDiffuseDist = st_ivas->hDiracDecBin[0]->hDiffuseDist; -#else - hDiffuseDist = st_ivas->hDiracDecBin->hDiffuseDist; -#endif nchan_transport = st_ivas->nchan_transport; band_grouping = hDirAC->band_grouping; hSpar = st_ivas->hSpar; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 4e709162129b182f9db51afe4e8aa26758016e30..a9f2c7b26d3d4fdaaaf6589eaddd825de0d9c186 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -148,7 +148,7 @@ ivas_error ivas_param_mc_dec_open( hParamMC->hoa_encoder = NULL; /* determine the synthesis config */ - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD || st_ivas->transport_config == output_config ) + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD || st_ivas->transport_config == output_config || output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { hParamMC->synthesis_conf = PARAM_MC_SYNTH_DIRECT; } @@ -1484,13 +1484,8 @@ void ivas_param_mc_dec_render( /*CLDFB*/ float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#else - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#endif /*Decorrelator*/ float onset_filter[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* format converter */ @@ -1686,36 +1681,31 @@ void ivas_param_mc_dec_render( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } -#endif ivas_binRenderer( st_ivas->hBinRenderer, -#ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG NULL, -#endif #endif st_ivas->hCombinedOrientationData, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t pos_idx; @@ -1725,13 +1715,12 @@ void ivas_param_mc_dec_render( { for ( ch = 0; ch < nchan_out_cldfb; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); } } } } -#endif /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); @@ -1755,13 +1744,8 @@ void ivas_param_mc_dec_render( { if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i]; ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i]; -#else - RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; - ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; -#endif } else { diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index d6b12947ef70498e08ca2123987f5594d6272c69..41cdf081fb4c0d16622744e798c2487706490fd4 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -651,22 +651,15 @@ static void ivas_mc_paramupmix_dec_sf( int16_t subframeIdx, idx_in, maxBand; float Cldfb_RealBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; int16_t slot_index_start; -#else - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif hMCParamUpmix = st_ivas->hMCParamUpmix; assert( hMCParamUpmix ); push_wmops( "ivas_mc_paramupmix_dec_sf" ); -#ifdef SPLIT_REND_WITH_HEAD_ROT slot_index_start = st_ivas->hTcBuffer->slots_rendered; -#endif for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ @@ -757,38 +750,33 @@ static void ivas_mc_paramupmix_dec_sf( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*LFE handling for split rendering cases*/ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } -#endif /* Implement binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, -#ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, -#endif + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t pos_idx; @@ -798,13 +786,12 @@ static void ivas_mc_paramupmix_dec_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); } } } } -#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -814,13 +801,8 @@ static void ivas_mc_paramupmix_dec_sf( for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; -#else - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; -#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][0] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 368f6e76b73251af322a48132a5a3ed6dca9ad0f..0c284a24366282fab421f0c224fb507d024a68e7 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -54,11 +54,7 @@ * Local function prototypes *-----------------------------------------------------------------------*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, uint16_t *nSamplesRendered, const PCM_RESOLUTION pcm_resolution, void *data ); -#else -static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, uint16_t *nSamplesRendered, int16_t *data ); -#endif /*--------------------------------------------------------------------------* @@ -87,6 +83,7 @@ ivas_error ivas_mct_dec( STnsData tnsData[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; Decoder_State **sts; float synth[CPE_CHANNELS][L_FRAME_PLUS]; + float *p_output_orig[2]; float output_lfe_ch[L_FRAME48k]; int32_t ivas_total_brate; ivas_error error; @@ -148,6 +145,16 @@ ivas_error ivas_mct_dec( /* MCT side bits decoder */ ivas_mct_side_bits( hMCT, st_ivas->hCPE, nCPE, st_ivas->hCPE[0]->hCoreCoder[0], st_ivas->bfi, st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream, ivas_total_brate, nb_bits_metadata ); + /* in case of switching from an SID frame (with ACELP core) to MCT, buffer of L_FRAME_PLUS samples is needed -> use synth[] as a temporary buffer */ + if ( st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) + { + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + p_output_orig[n] = output[n]; + output[n] = synth[n]; + } + } + for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { st_ivas->hCPE[cpe_id]->hCoreCoder[0]->BER_detect |= st_ivas->BER_detect; @@ -232,6 +239,15 @@ ivas_error ivas_mct_dec( ivas_mdct_core_reconstruct( hCPE, x, synth, fUseTns[cpe_id], 1 ); + /* set pointers back */ + if ( cpe_id == 0 && st_ivas->hCPE[0]->hCoreCoder[0]->last_core == ACELP_CORE ) + { + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + output[n] = p_output_orig[n]; + } + } + /*----------------------------------------------------------------* * CoreCoder Post-processing and updates *----------------------------------------------------------------*/ @@ -263,7 +279,6 @@ ivas_error ivas_mct_dec( #endif } /* n_channels loop */ - /* synthesis synchronization between stereo modes */ if ( !st_ivas->sba_dirac_stereo_flag || ( st_ivas->ivas_format == SBA_ISM_FORMAT && cpe_id < nCPE - 2 ) ) { @@ -646,15 +661,11 @@ void ivas_mct_dec_close( /*! r : MC format mode */ ivas_error ivas_mc_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t idx, /* i : LS config. index */ - uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t idx, /* i : LS config. index */ + uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { AUDIO_CONFIG signaled_config; @@ -673,6 +684,13 @@ ivas_error ivas_mc_dec_config( { st_ivas->transport_config = signaled_config; } + else if ( st_ivas->transport_config != signaled_config ) + { +#ifdef DEBUGGING + fprintf( stderr, "\nError: Switching of MC configurations is not supported!\n" ); +#endif + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong MC configuration signalled!" ); + } /* select MC format mode */ st_ivas->mc_mode = ivas_mc_mode_select( ivas_mc_map_output_config_to_mc_ls_setup( signaled_config ), st_ivas->hDecoderConfig->ivas_total_brate ); @@ -680,14 +698,9 @@ ivas_error ivas_mc_dec_config( /* MC format switching */ if ( st_ivas->ini_frame != 0 ) { - if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || st_ivas->transport_config != signaled_config || last_mc_mode != st_ivas->mc_mode ) + if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || last_mc_mode != st_ivas->mc_mode ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif - { return error; } @@ -708,14 +721,10 @@ ivas_error ivas_mc_dec_config( *-------------------------------------------------------------------------*/ static ivas_error ivas_mc_dec_reconfig( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame (JBM) */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old, nchan_hp20_old; @@ -799,11 +808,7 @@ static ivas_error ivas_mc_dec_reconfig( tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1117,21 +1122,28 @@ static ivas_error ivas_mc_dec_reconfig( if ( ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && st_ivas->hLFE == NULL ) { - int32_t binauralization_delay_ns = st_ivas->binaural_latency_ns; + int32_t delay_ns = st_ivas->binaural_latency_ns; if ( st_ivas->hBinRenderer != NULL ) { if ( st_ivas->hBinRenderer->render_lfe ) { /* Account for filterbank delay */ - binauralization_delay_ns += IVAS_FB_DEC_DELAY_NS; + delay_ns += IVAS_FB_DEC_DELAY_NS; } else { - binauralization_delay_ns = 0; + delay_ns = 0; + } + } + else + { + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( st_ivas->cldfbSynDec[0] != NULL ) ) + { + delay_ns += IVAS_FB_DEC_DELAY_NS; } } - if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, binauralization_delay_ns ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, delay_ns ) ) != IVAS_ERR_OK ) { return error; } @@ -1182,58 +1194,33 @@ static ivas_error ivas_mc_dec_reconfig( output_config = st_ivas->hDecoderConfig->output_config; /* binaural renderers*/ - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { /* remove unneeded binaural renderers */ if ( st_ivas->hBinRenderer != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) ) { ivas_binRenderer_close( &st_ivas->hBinRenderer ); + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) + { + efap_free_data( &st_ivas->hEFAPdata ); + } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend[0] != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hIntSetup.output_config != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) -#else - if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hIntSetup.output_config != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) -#endif { - -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); -#endif + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); } if ( st_ivas->hBinRendererTd != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) ) { -#ifdef NONBE_FIX_1045_ISM_BITRATE_SWITCHING ivas_td_binaural_close( &st_ivas->hBinRendererTd ); -#else - if ( st_ivas->hBinRendererTd->HrFiltSet_p->ModelParams.modelROM == TRUE ) - { - ivas_td_binaural_close( &st_ivas->hBinRendererTd ); - st_ivas->hHrtfTD = NULL; - } -#endif } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0] != NULL ) -#else - if ( st_ivas->hDiracDecBin != NULL ) -#endif { if ( st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); -#else - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); -#endif } } @@ -1262,39 +1249,22 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper, 1 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper ) ) != IVAS_ERR_OK ) -#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT st_ivas->hCrendWrapper->hCrend[0] = NULL; st_ivas->hCrendWrapper->hHrtfCrend = NULL; if ( ( st_ivas->hCrendWrapper->hCrend[0] = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } -#else - st_ivas->hCrendWrapper->hCrend = NULL; - st_ivas->hCrendWrapper->hHrtfCrend = NULL; - if ( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); - } -#endif } } else if ( st_ivas->hCrendWrapper == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) -#endif + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 907affdae1d5362ccf35bbd4a117f0566d4c23f3..7dcab1ad082e19dfe563e1478659a0183c4c25bc 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -62,7 +62,7 @@ ivas_error ivas_td_binaural_open( } return ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, num_src, st_ivas->ivas_format, - st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns ); + st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hRenderConfig->distAtt, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns ); } @@ -230,7 +230,6 @@ ivas_error ivas_td_binaural_renderer_sf( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * ivas_td_binaural_renderer_sf_splitBinaural() * @@ -238,9 +237,9 @@ ivas_error ivas_td_binaural_renderer_sf( *---------------------------------------------------------------------*/ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - int16_t nSamplesRendered /* i : number of samples to render */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t nSamplesRendered /* i : number of samples to render */ ) { int16_t i; @@ -252,15 +251,15 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( int16_t original_subframes_rendered; int16_t original_slots_rendered; float *p_bin_output[BINAURAL_CHANNELS]; - float output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV + float output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; push_wmops( "ivas_td_binaural_renderer_sf_splitBinaural" ); - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; /* If not yet allocated, open additional instances of TD renderer */ for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) { - if ( st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i] != NULL ) + if ( st_ivas->hTdRendHandles[i] != NULL ) { continue; } @@ -271,8 +270,9 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity, + st_ivas->hRenderConfig->distAtt, st_ivas->hTransSetup, - &st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i], + &st_ivas->hTdRendHandles[i], &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) { return error; @@ -333,7 +333,7 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( /* Render */ if ( pos_idx != 0 ) { - st_ivas->hBinRendererTd = st_ivas->hSplitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; + st_ivas->hBinRendererTd = st_ivas->hTdRendHandles[pos_idx - 1]; } if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_bin_output, nSamplesRendered ) ) != IVAS_ERR_OK ) @@ -369,4 +369,3 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( pop_wmops(); return IVAS_ERR_OK; } -#endif diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index cfef5d17cac687a6d3e64865155edbdaed604fdf..465f013317990d726414c8a15ff69994d35fb084 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -189,14 +189,10 @@ void ivas_omasa_data_close( *--------------------------------------------------------------------------*/ ivas_error ivas_omasa_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ - void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ ) { int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD; @@ -240,11 +236,7 @@ ivas_error ivas_omasa_dec_config( { st_ivas->hCPE[0]->nchan_out = 1; } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -300,7 +292,6 @@ ivas_error ivas_omasa_dec_config( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { /* the full number of hIsmMetaData are needed for EXT output */ -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE if ( st_ivas->hIsmMetaData[0] == NULL ) { if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) @@ -315,17 +306,6 @@ ivas_error ivas_omasa_dec_config( ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[k] ); } } -#else - n_MD = st_ivas->nchan_ism; - ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 ); - - if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD ); -#endif } else { @@ -340,20 +320,15 @@ ivas_error ivas_omasa_dec_config( return error; } } -#ifdef NONBE_FIX_1065_ISM_MD_HANDLE else { ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[0] ); } -#endif } else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { n_MD = st_ivas->nchan_ism; -#ifndef NONBE_FIX_1065_ISM_MD_HANDLE - ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 ); -#endif if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK ) { return error; @@ -426,20 +401,11 @@ ivas_error ivas_omasa_dec_config( } else { -#ifdef NONBE_FIX_1045_ISM_BITRATE_SWITCHING if ( st_ivas->hBinRendererTd != NULL ) { /* TD renderer handle */ ivas_td_binaural_close( &st_ivas->hBinRendererTd ); } -#else - if ( st_ivas->hBinRendererTd != NULL && st_ivas->hBinRendererTd->HrFiltSet_p->ModelParams.modelROM == TRUE ) - { - /* TD renderer handle */ - ivas_td_binaural_close( &st_ivas->hBinRendererTd ); - st_ivas->hHrtfTD = NULL; - } -#endif /* ISM renderer handle + ISM data handle */ ivas_omasa_separate_object_renderer_close( st_ivas ); } @@ -497,18 +463,9 @@ ivas_error ivas_omasa_dec_config( * TD Decorrelator *-----------------------------------------------------------------*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0] != NULL ) -#else - if ( st_ivas->hDiracDecBin != NULL ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) -#endif - { return error; } @@ -783,6 +740,9 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; ivas_error error; float *p_sepobj[MAX_NUM_OBJECTS]; + int16_t slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) { @@ -794,13 +754,51 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( /* reset combined orientation access index before calling the td renderer */ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - return error; + int16_t slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots; + float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + float *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */ + + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; n++ ) + { + p_rend_obj[n] = &output_f[n][0]; + } + + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + nchan_transport_orig = st_ivas->nchan_transport; + st_ivas->nchan_transport = st_ivas->nchan_ism; + + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */ + { + return error; + } + st_ivas->nchan_transport = nchan_transport_orig; + cldfb_slots = *nSamplesRendered / num_cldfb_bands; + + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + { + for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) + { + cldfbAnalysis_ts( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] ); + + /* note: this intentionally differs from OSBA by: no scaling by 0.5 */ + v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands ); + v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands ); + } + } } - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + else { - v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); + } } return IVAS_ERR_OK; diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 7473cbaa75b21657e10829c9737edc16e54236b7..eaf5d11a7e894e41a6aab1229e5329a593567797 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -137,6 +137,9 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV float *p_sepobj[BINAURAL_CHANNELS]; int16_t channel_offset; + int16_t slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { @@ -150,40 +153,41 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( return error; } + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig; - int16_t cldfb_slots, slot_idx_start; + int16_t cldfb_slots; float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - num_cldfb_bands = st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; nchan_transport_orig = st_ivas->nchan_transport; st_ivas->nchan_transport = st_ivas->nchan_ism; - slot_idx_start = st_ivas->hTcBuffer->n_samples_rendered / num_cldfb_bands; + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } + st_ivas->nchan_transport = nchan_transport_orig; cldfb_slots = *nSamplesRendered / num_cldfb_bands; - for ( n = 0; n < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) { for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) { - cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[n] ); + cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] ); for ( b = 0; b < num_cldfb_bands; b++ ) { - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + ( 0.5f * Cldfb_RealBuffer[b] ); - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + ( 0.5f * Cldfb_ImagBuffer[b] ); } } @@ -191,8 +195,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( } else { -#endif - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; @@ -206,9 +208,8 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( output_f[n][i] = 0.5f * output_f[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif + return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 1be9e6182943ca9e7efcba741043e5094556c64f..7284155d9eab659341c722d0536d06216ebfc2c4 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -34,9 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot_rend.h" -#endif #include "ivas_stat_dec.h" #ifdef DEBUGGING #include "debug.h" @@ -79,21 +76,13 @@ void ivas_renderer_select( st_ivas->hCombinedOrientationData->shd_rot_max_order = -1; } - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( st_ivas->ivas_format == ISM_FORMAT ) { if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL ) -#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -104,11 +93,7 @@ void ivas_renderer_select( } else /* ISM_MODE_DISC */ { - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { #ifdef DEBUGGING if ( st_ivas->hDecoderConfig->force_rend == FORCE_CLDFB_RENDERER ) @@ -143,11 +128,7 @@ void ivas_renderer_select( { *internal_config = output_config; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL ) -#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -160,11 +141,7 @@ void ivas_renderer_select( { *internal_config = IVAS_AUDIO_CONFIG_HOA3; - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL -#ifdef SPLIT_REND_WITH_HEAD_ROT - || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { *renderer_type = RENDERER_BINAURAL_FASTCONV; } @@ -206,11 +183,7 @@ void ivas_renderer_select( { *internal_config = output_config; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL ) -#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -223,11 +196,7 @@ void ivas_renderer_select( { *internal_config = transport_config; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif { #ifdef DEBUGGING if ( ( ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) || ( st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) ) && st_ivas->mc_mode == MC_MODE_MCT && st_ivas->hDecoderConfig->force_rend != FORCE_CLDFB_RENDERER ) @@ -436,7 +405,7 @@ void ivas_renderer_select( else if ( st_ivas->ivas_format == MC_FORMAT ) { *internal_config = transport_config; - if ( st_ivas->mc_mode == MC_MODE_MCT && *internal_config != output_config ) + if ( st_ivas->mc_mode == MC_MODE_MCT && *internal_config != output_config && output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { if ( output_config != IVAS_AUDIO_CONFIG_FOA && output_config != IVAS_AUDIO_CONFIG_HOA2 && output_config != IVAS_AUDIO_CONFIG_HOA3 ) { @@ -450,7 +419,7 @@ void ivas_renderer_select( else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) { *internal_config = transport_config; - if ( *internal_config != output_config ) + if ( *internal_config != output_config && output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { if ( output_config != IVAS_AUDIO_CONFIG_FOA && output_config != IVAS_AUDIO_CONFIG_HOA2 && output_config != IVAS_AUDIO_CONFIG_HOA3 ) { @@ -475,7 +444,10 @@ void ivas_renderer_select( } else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { - *internal_config = output_config; + if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) + { + *internal_config = output_config; + } /* No rendering for 1TC to Mono or Stereo and 2TC to Stereo */ if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index bc895de45c81d75db7b121615465823731503f5b..ef5da3cb5db9d8510a35f401d439b68886d334d3 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -1203,6 +1203,7 @@ int16_t ivas_qmetadata_dec_sid_decode( float direction_vector[3]; int16_t metadata_sid_bits; /* bits allocated to SID for metadata */ int16_t bits_delta, bits_dir; + int16_t sba_spar_bitlen; #ifdef DEBUG_MODE_QMETADATA static FILE *pF = NULL; static FILE *pF_azi = NULL; @@ -1221,7 +1222,8 @@ int16_t ivas_qmetadata_dec_sid_decode( if ( ivas_format == SBA_FORMAT ) { - metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 2 - SID_FORMAT_NBITS; /* -1 for inactive mode header bit*/ + sba_spar_bitlen = ivas_sba_spar_sid_bitlen( nchan_transport ); + metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - sba_spar_bitlen - SID_FORMAT_NBITS - SBA_ORDER_BITS - SBA_PLANAR_BITS - 1; /* -1 for inactive mode header bit*/ } else { diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 30779c35de49e3c87b73c9a8dcadafaf65695a40..8f4037773b64f20a077daddf7e89561d898a9a8c 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -390,154 +390,6 @@ const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS] = 6.716062e-01f, 1.011804e+00f, 1.796875e+00f, 2.804382e+00f, 4.623130e+00f, 7.802667e+00f, 1.045446e+01f, 1.379538e+01f }; -/*----------------------------------------------------------------------------------* - * FASTCONV and PARAMETRIC binaural renderer ROM tables - *----------------------------------------------------------------------------------*/ - -const float dmxmtx_table[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 }, -}; - - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------* - * Binuaral split rendering ROM tables - *-----------------------------------------------------------------------*/ - -/* rotations in this array are relative to ref rotation */ -const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; -const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; -const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; -const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; - -const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; -const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; -const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; -const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; - -const int16_t ivas_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60 -}; - -const int32_t ivas_split_rend_huff_p_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3] = -{ - {0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12}, - {6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61}, - {12,7,125},{13,8,254},{14,8,255} -}; - -const int32_t ivas_split_rend_huff_p_d_diff_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3] = -{ - { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, - { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, - { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, - { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } -}; - -const int32_t ivas_split_rend_huff_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3] = -{ - { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, - { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, - { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, - { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } -}; - -const int32_t ivas_split_rend_huff_pred63_consts[IVAS_SPLIT_REND_PRED_63QUANT_PNTS][3] = -{ - {-31,11,2040}, - {-30,11,2041}, - {-29,11,2042}, - {-28,11,2043}, - {-27,10,1012}, - {-26,10,1013}, - {-25,10,1014}, - {-24,10,1015}, - {-23,9,498}, - {-22,9,499}, - {-21,9,500}, - {-20,9,501}, - {-19,8,242}, - {-18,8,243}, - {-17,8,244}, - {-16,8,245}, - {-15,7,112}, - {-14,7,113}, - {-13,7,114}, - {-12,7,115}, - {-11,6,48}, - {-10,6,49}, - {-9,6,50}, - {-8,6,51}, - {-7,5,16}, - {-6,5,17}, - {-5,5,18}, - {-4,5,19}, - {-3,4,2}, - {-2,4,3}, - {-1,4,4}, - {0,3,0}, - {1,4,5}, - {2,4,6}, - {3,4,7}, - {4,5,20}, - {5,5,21}, - {6,5,22}, - {7,5,23}, - {8,6,52}, - {9,6,53}, - {10,6,54}, - {11,6,55}, - {12,7,116}, - {13,7,117}, - {14,7,118}, - {15,7,119}, - {16,7,120}, - {17,8,246}, - {18,8,247}, - {19,8,248}, - {20,9,502}, - {21,9,503}, - {22,9,504}, - {23,9,505}, - {24,10,1016}, - {25,10,1017}, - {26,10,1018}, - {27,10,1019}, - {28,11,2044}, - {29,11,2045}, - {30,11,2046}, - {31,11,2047}, -}; - -const int32_t ivas_split_rend_huff_pred31_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3] = -{ - {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, - {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, - {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, - {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, - {2,4,10},{3,4,11},{4,5,26},{5,5,27}, - {6,6,58},{7,6,59},{8,7,122},{9,7,123}, - {10,7,124},{11,8,252},{12,9,508},{13,9,509}, - {14,10,1022},{15,10,1023}, -}; - -const int32_t ivas_split_rend_huff_roll_pred_consts[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] = -{ - {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, - {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, - {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, - {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, - {2,4,10},{3,4,11},{4,5,26},{5,5,27}, - {6,6,58},{7,6,59},{8,7,122},{9,7,123}, - {10,7,124},{11,8,252},{12,9,508},{13,9,509}, -{14,10,1022},{15,10,1023}, -}; - -#endif - /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index d7c5f9c596d01bc241a9fe4dc1805ba9a2ac6221..5f3730470a8c40276afcb9e71c73218375cf2b41 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -97,39 +97,6 @@ extern const float dirac_dithering_azi_scale[DIRAC_DIFFUSE_LEVELS]; extern const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS]; -/*----------------------------------------------------------------------------------* - * FASTCONV and PARAMETRIC binaural renderer ROM tables - *----------------------------------------------------------------------------------*/ - -extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------* - * Binuaral split rendering ROM tables - *-----------------------------------------------------------------------*/ - -extern const float ivas_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; -extern const float ivas_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float ivas_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float ivas_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; -extern const float ivas_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; - -extern const float ivas_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; -extern const float ivas_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; -extern const float ivas_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; - -extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; -extern const int16_t ivas_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; -extern const int32_t ivas_split_rend_huff_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_pred63_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_pred31_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_roll_pred_consts[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_p_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_p_d_diff_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t split_rend_brate_tbl[]; -#endif - - /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 87cc36978f5e5a0f7e0f3137e72b1a54807ca915..5bc779829ba186d933d3795086778d2631a29366 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -70,7 +70,7 @@ void ivas_sba_set_cna_cng_flag( 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 ) + else if ( st_ivas->nchan_transport == 2 && st_ivas->ivas_format != SBA_ISM_FORMAT ) { for ( n = 0; n < CPE_CHANNELS; n++ ) { @@ -101,14 +101,10 @@ void ivas_sba_set_cna_cng_flag( *-------------------------------------------------------------------*/ ivas_error ivas_sba_dec_reconfigure( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - uint16_t *nSamplesFlushed, /* o : number of samples flushed */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t *nSamplesFlushed, /* o : number of samples flushed */ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, nchan_hp20_old; @@ -124,6 +120,7 @@ ivas_error ivas_sba_dec_reconfigure( ivas_error error; ISM_MODE ism_mode_old; int16_t granularity_new; + int16_t nchan_transport; ism_mode_old = st_ivas->ism_mode; hDecoderConfig = st_ivas->hDecoderConfig; @@ -143,7 +140,7 @@ ivas_error ivas_sba_dec_reconfigure( if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { - if ( ivas_total_brate >= IVAS_256k ) + if ( ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ) == ISM_SBA_MODE_DISC ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; } @@ -179,11 +176,7 @@ ivas_error ivas_sba_dec_reconfigure( /* copy the logic from ivas_renderer_select(), because calling this function has too many side effects that would affect the flushing */ if ( ivas_get_sba_num_TCs( ivas_total_brate, sba_order_internal ) <= 2 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL ) -#endif { renderer_type_new = RENDERER_BINAURAL_PARAMETRIC; } @@ -194,11 +187,7 @@ ivas_error ivas_sba_dec_reconfigure( } else { - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL -#ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { renderer_type_new = RENDERER_BINAURAL_FASTCONV; } @@ -224,11 +213,7 @@ ivas_error ivas_sba_dec_reconfigure( st_ivas->sba_analysis_order = sba_analysis_order_old_flush; st_ivas->hDecoderConfig->ivas_total_brate = last_ivas_total_brate; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, granularity_new, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, st_ivas->mc_mode, ism_mode_old, nSamplesFlushed, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, granularity_new, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, st_ivas->mc_mode, ism_mode_old, nSamplesFlushed, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -450,6 +435,7 @@ ivas_error ivas_sba_dec_reconfigure( * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ + nchan_transport = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { if ( ism_mode_old == ISM_MODE_NONE && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) @@ -519,7 +505,8 @@ ivas_error ivas_sba_dec_reconfigure( return error; } - st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; + nchan_transport += st_ivas->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; } else if ( ism_mode_old == ISM_SBA_MODE_DISC && st_ivas->ism_mode == ISM_MODE_NONE ) { @@ -531,24 +518,18 @@ ivas_error ivas_sba_dec_reconfigure( /* Time Domain binaural renderer handle */ if ( st_ivas->hBinRendererTd != NULL ) { -#ifdef NONBE_FIX_1045_ISM_BITRATE_SWITCHING ivas_td_binaural_close( &st_ivas->hBinRendererTd ); -#else - if ( st_ivas->hBinRendererTd->HrFiltSet_p->ModelParams.modelROM == TRUE ) - { - ivas_td_binaural_close( &st_ivas->hBinRendererTd ); - st_ivas->hHrtfTD = NULL; - } -#endif } + + nchan_transport = st_ivas->nchan_transport; nchan_transport_old += st_ivas->nchan_ism; + st_ivas->ism_mode = ISM_MODE_NONE; } else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; - nCPE_old = st_ivas->nCPE; - nchan_transport_old = st_ivas->nchan_transport; + nchan_transport = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; nchan_transport_old += st_ivas->nchan_ism; } } @@ -571,21 +552,12 @@ ivas_error ivas_sba_dec_reconfigure( * TD Decorrelator *-----------------------------------------------------------------*/ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0] != NULL ) { if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) { return error; } -#else - if ( st_ivas->hDiracDecBin != NULL ) - { - if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif } /*-----------------------------------------------------------------* @@ -715,11 +687,7 @@ void ivas_sba_dec_digest_tc( ivas_spar_dec_digest_tc( st_ivas, st_ivas->nchan_transport, nCldfbSlots, nSamplesForRendering ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) -#else - if ( st_ivas->hDiracDecBin != NULL && ( st_ivas->hDiracDecBin->useTdDecorr ) ) -#endif { int16_t nSamplesLeftForTD, default_frame; float *decorr_signal[BINAURAL_CHANNELS]; @@ -738,17 +706,9 @@ void ivas_sba_dec_digest_tc( { int16_t nSamplesToDecorr = min( nSamplesLeftForTD, default_frame ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDiracDecBin[0]->hTdDecorr ) -#else - if ( st_ivas->hDiracDecBin->hTdDecorr ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_td_decorr_process( st_ivas->hDiracDecBin[0]->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); -#else - ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); -#endif } for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index 123e51da4bdb24f1018c75fc1015c18922d2de24..1782262cb3817685c54abc0fc931496f3117de9a 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -395,10 +395,16 @@ static void map_params_dirac_to_stereo( } } + /* Clamp values here. [-1, 1] is the allowed range, but due to precision issues they can be slightly off which can cause problems later. */ side_gain[b] *= sqrtf( 1.f - diffuseness[b] ); + side_gain[b] = max( min( side_gain[b], 1 ), -1 ); side_gain[b + STEREO_DFT_BAND_MAX] *= sqrtf( 1.f - diffuseness[b] ); + side_gain[b + STEREO_DFT_BAND_MAX] = max( min( side_gain[b + STEREO_DFT_BAND_MAX], 1 ), -1 ); + /* for residual prediction gain, allowed range is [0, 1]*/ res_pred_gain[b] = diffuseness[b] * ( 1.0f - surrCoh[b] ); + res_pred_gain[b] = max( min( res_pred_gain[b], 1 ), 0 ); res_pred_gain[b + STEREO_DFT_BAND_MAX] = diffuseness[b] * ( 1.0f - surrCoh[b] ); + res_pred_gain[b + STEREO_DFT_BAND_MAX] = max( min( res_pred_gain[b + STEREO_DFT_BAND_MAX], 1 ), 0 ); } } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 533949fd6cf71f82ede4947db55867d237e8d7f6..aed98cbe3bb30ef2be3660824579b384b50d9880 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -354,7 +354,7 @@ ivas_error ivas_spar_dec( /* read DirAC bitstream */ if ( st_ivas->hQMetaData != NULL ) { - ivas_dirac_dec_read_BS( hDecoderConfig->ivas_total_brate, st0, st_ivas->hDirAC, st_ivas->hSpatParamRendCom, st_ivas->hQMetaData, nb_bits_read, last_bit_pos, ivas_get_hodirac_flag( hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ), st_ivas->hSpar->dirac_to_spar_md_bands ); + ivas_dirac_dec_read_BS( hDecoderConfig->ivas_total_brate, st0, st_ivas->hDirAC, st_ivas->hSpatParamRendCom, st_ivas->hQMetaData, nb_bits_read, last_bit_pos, ivas_get_hodirac_flag( hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ), st_ivas->nchan_transport, st_ivas->hSpar->dirac_to_spar_md_bands ); } if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -368,7 +368,7 @@ ivas_error ivas_spar_dec( if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) { - last_bit_pos -= SID_FORMAT_NBITS; + last_bit_pos -= ( SID_FORMAT_NBITS + SBA_PLANAR_BITS + SBA_ORDER_BITS ); } nb_bits_read_orig = *nb_bits_read; last_bit_pos -= nb_bits_read_orig; @@ -403,7 +403,7 @@ ivas_error ivas_spar_dec( if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) { int16_t zero_pad_bits; - *nb_bits_read += SID_FORMAT_NBITS; + *nb_bits_read += SID_FORMAT_NBITS + SBA_PLANAR_BITS + SBA_ORDER_BITS; 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; @@ -1565,6 +1565,7 @@ void ivas_spar_dec_upmixer_sf( { md_idx = hSpar->render_to_md_map[ts + slot_idx_start]; ivas_spar_get_parameters( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat ); + if ( ( hDecoderConfig->ivas_total_brate < IVAS_24k4 ) && ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) ) { for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) @@ -1679,11 +1680,7 @@ void ivas_spar_dec_upmixer_sf( } else { - if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) ) && + if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) && !( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) ) { for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 5e312dadb504962df39f0158b852f40e2886ba5e..b920d4d019e65c5c8064be5e8f35cf9ad4fe8eba 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2385,6 +2385,7 @@ static void ivas_parse_parameter_bitstream_dtx( float pr_min_max[2]; int16_t pr_q_lvls, pr, pd, pd_q_lvls, pr_pd_bits; int16_t zero_pad_bits, sid_bits_len; + int16_t sba_spar_bitlen; sid_bits_len = st0->next_bit_pos; pr_min_max[0] = pSpar_md->min_max[0]; @@ -2443,7 +2444,8 @@ static void ivas_parse_parameter_bitstream_dtx( } sid_bits_len = st0->next_bit_pos - sid_bits_len; - zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; + sba_spar_bitlen = ivas_sba_spar_sid_bitlen( num_dmx_per_band[0] ); + zero_pad_bits = sba_spar_bitlen - sid_bits_len; assert( zero_pad_bits >= 0 ); if ( num_dmx_per_band[0] == 2 ) { diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 7d705c8213856ec748846af6295f1a6d376ebc2f..913867183a379922fe38b880cb79618403c092a8 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -812,32 +812,35 @@ typedef struct renderer_struct } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; -#ifndef SPLIT_REND_WITH_HEAD_ROT -/* Fastconv binaural data structure */ -typedef struct ivas_binaural_rendering_struct + +/*----------------------------------------------------------------------------------* + * IVAS decoder specific ISAR wrapper structures + *----------------------------------------------------------------------------------*/ + +typedef struct { - /* Common variables for all modules */ - IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ - EFAP_HANDLE hEFAPdata; /* EFAP structure*/ - float *hoa_dec_mtx; /* pointer to HOA decoder mtx */ - int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ - int16_t max_band; /* band upto which rendering is performed */ - int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ - int16_t timeSlots; /* number of time slots of binaural renderer */ - int16_t nInChannels; /* number input channels */ - int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ - IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ - - /* Convolution module structure */ - BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; - - /* Variables related to reverberator module */ - float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; - REVERB_STRUCT_HANDLE hReverb; - -} BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; -#endif + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +} ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; + +typedef struct +{ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + IVAS_AUDIO_CONFIG config; + +} ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA, *ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; + +typedef struct +{ + ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ + SPLIT_REND_WRAPPER splitrend; + ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ + int16_t numTdSamplesPerChannelCached; + +} ISAR_DEC_SPLIT_REND_WRAPPER, *ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE; /*----------------------------------------------------------------------------------* * MASA decoder structures @@ -969,38 +972,6 @@ typedef struct jbm_metadata_structure } JBM_METADATA, *JBM_METADATA_HANDLE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split rendering structures - *----------------------------------------------------------------------------------*/ - -typedef struct -{ - float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - -} IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; - -typedef struct -{ - float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - AUDIO_CONFIG config; - -} IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA, *IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; - -typedef struct -{ - IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ - IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ - SPLIT_REND_WRAPPER splitrend; - IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ - int16_t numTdSamplesPerChannelCached; - -} IVAS_DEC_SPLIT_REND_WRAPPER; -#endif - - /*----------------------------------------------------------------------------------* * Decoder configuration structure *----------------------------------------------------------------------------------*/ @@ -1031,9 +1002,6 @@ typedef struct decoder_config_structure int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ #endif int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t Opt_Limiter; -#endif IVAS_RENDER_FRAMESIZE render_framesize; int16_t Opt_delay_comp; /* flag indicating delay compensation active */ @@ -1114,11 +1082,7 @@ typedef struct Decoder_Struct BINAURAL_RENDERER_HANDLE hBinRenderer; /* fastconv binaural renderer handle */ BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; /* Time domain binaural object renderer handle */ TDREND_HRFILT_FiltSet_t *hHrtfTD; /* pointer to HRTF data for TD renderer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; /* parametric binaural renderer handle */ -#else - DIRAC_DEC_BIN_HANDLE hDiracDecBin; /* parametric binaural renderer handle */ -#endif LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; /* MC LS configuration convertion handle */ EFAP_HANDLE hEFAPdata; /* EFAP structure */ VBAP_HANDLE hVBAPdata; /* VBAP structure */ @@ -1143,9 +1107,8 @@ typedef struct Decoder_Struct int16_t flag_omasa_brate; -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_SPLIT_REND_WRAPPER hSplitBinRend; /* split binuaral rendering handle */ -#endif + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; /* TD object renderer handles */ /* JBM module */ DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */ diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 5bca3fc63bacf4fb214d8094fba87d83471417b5..ebef0644ee3dfbf60bc89cdb20ceb4d8600f8708 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -48,10 +48,10 @@ *-----------------------------------------------------------------------*/ /* The SVD is sensitive to changes to the following constants, so please be careful when trying to tune things */ -#define SVD_MINIMUM_VALUE 1e-32f /* minimum value */ -#define CONVERGENCE_FACTOR 1.19209290e-07f /* factor for SVD convergence */ -#define SVD_MAX_NUM_ITERATION 75 /* maximum number of interations before exiting the SVD */ -#define SVD_ZERO_FLUSH_THRESHOLD 1.0e-20f +#define SVD_MINIMUM_VALUE 1e-32f /* minimum value */ +#define CONVERGENCE_FACTOR 1.0e-04f /* factor for SVD convergence */ +#define SVD_MAX_NUM_ITERATION 75 /* maximum number of interations before exiting the SVD */ +#define SVD_ZERO_FLUSH_THRESHOLD 0.0f /*-----------------------------------------------------------------------* diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 58eac4e99e35ac2bda6eb368c9fed0bae6f9d76f..35d460da39c84b27f31d4eb7275d1bc536a69ea7 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -34,6 +34,8 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#include "isar_prot.h" +#include "lib_isar_pre_rend.h" #include "prot.h" #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" @@ -109,24 +111,19 @@ static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSampl static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); -#ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, const IVAS_DEC_PCM_TYPE pcmType, void *data ); -#else -static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, int16_t *data ); -#endif static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); -#ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf ); -#else -static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, int16_t *pcmBuf ); -#endif static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, int16_t *nSamplesBuffered ); -#ifdef SPLIT_REND_WITH_HEAD_ROT static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType ); static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset ); static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int16_t nZeroSamples ); -#endif +static ivas_error isar_set_split_rend_setup( ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, ISAR_SPLIT_REND_BITS_DATA *splitRendBits ); +static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas ); +static ivas_error ivas_dec_init_split_rend( Decoder_Struct *st_ivas ); +static ivas_error ivas_create_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); +static void ivas_destroy_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ); @@ -250,6 +247,43 @@ ivas_error IVAS_DEC_Open( } +/*-------------------------------------------------------------------------* + * isar_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ + +static ivas_error isar_set_split_rend_setup( + ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; + + if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } + + ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); + + if ( hCombinedOrientationData != NULL ) + { + isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); + } + + return IVAS_ERR_OK; +} + /*---------------------------------------------------------------------* * init_decoder_config() * @@ -271,9 +305,6 @@ static void init_decoder_config( hDecoderConfig->Opt_non_diegetic_pan = 0; hDecoderConfig->non_diegetic_pan_gain = 0; hDecoderConfig->Opt_tsm = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT - hDecoderConfig->Opt_Limiter = 1; -#endif hDecoderConfig->Opt_delay_comp = 0; hDecoderConfig->Opt_ExternalOrientation = 0; hDecoderConfig->Opt_dpid_on = 0; @@ -305,6 +336,9 @@ void IVAS_DEC_Close( ( *phIvasDec )->hVoIP = NULL; } + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); + if ( ( *phIvasDec )->st_ivas ) { ivas_destroy_dec( ( *phIvasDec )->st_ivas ); @@ -463,12 +497,10 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->render_framesize = renderFramesize; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { hDecoderConfig->Opt_Headrotation = TRUE; } -#endif /* Set decoder parameters to initial values */ if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) @@ -476,6 +508,15 @@ ivas_error IVAS_DEC_Configure( return error; } + /* create ISAR handle */ + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); + } + } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { hIvasDec->st_ivas->ivas_format = MONO_FORMAT; @@ -492,7 +533,6 @@ ivas_error IVAS_DEC_Configure( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * IVAS_DEC_EnableSplitRendering( ) * @@ -500,14 +540,10 @@ ivas_error IVAS_DEC_Configure( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_EnableSplitRendering( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ ) { DECODER_CONFIG_HANDLE hDecoderConfig; - ivas_error error; - - error = IVAS_ERR_OK; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -519,11 +555,8 @@ ivas_error IVAS_DEC_EnableSplitRendering( hDecoderConfig->Opt_Headrotation = 1; hDecoderConfig->render_framesize = IVAS_RENDER_FRAMESIZE_20MS; - hDecoderConfig->Opt_Limiter = 0; - - return error; + return IVAS_ERR_OK; } -#endif /*---------------------------------------------------------------------* * get_render_framesize_ms( ) @@ -556,6 +589,15 @@ ivas_error IVAS_DEC_SetRenderFramesize( hIvasDec->st_ivas->hDecoderConfig->render_framesize = render_framesize; + if ( hIvasDec->st_ivas->hExtOrientationData != NULL ) + { + hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_framesize; + } + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_framesize; + } + return IVAS_ERR_OK; } @@ -845,16 +887,12 @@ ivas_error IVAS_DEC_FeedFrame_Serial( ivas_error IVAS_DEC_GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o :indication that the decoder needs a new frame */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ ) { ivas_error error; @@ -884,16 +922,14 @@ ivas_error IVAS_DEC_GetSamples( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------* * Binaural split rendering setup *----------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL && ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - ivas_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend, hIvasDec->st_ivas->hCombinedOrientationData ); + isar_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat ); } -#endif hIvasDec->updateOrientation = false; } @@ -927,19 +963,11 @@ ivas_error IVAS_DEC_GetSamples( if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { /* setup */ - -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) -#endif { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /* :TODO: change nSamplesAsked also if we are in 5ms 0dof split rendering... */ -#endif } { /* check if we need to run the setup function, tc decoding and feeding the renderer */ @@ -1007,11 +1035,7 @@ ivas_error IVAS_DEC_GetSamples( /* render IVAS frames directly to the output buffer */ nSamplesToRender = nSamplesAsked - nSamplesRendered; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1036,7 +1060,6 @@ ivas_error IVAS_DEC_GetSamples( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * IVAS_DEC_GetSplitBinauralBitstream( ) * @@ -1044,11 +1067,11 @@ ivas_error IVAS_DEC_GetSamples( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ ) { Decoder_Struct *st_ivas; @@ -1062,13 +1085,14 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( int16_t numSamplesPerChannelToDecode; int16_t i, j; ivas_error error; - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; int16_t max_band; int16_t pcm_out_flag; int16_t td_input; int16_t numPoses; int16_t slots_rendered, slots_rendered_new; int16_t ro_md_flag; + IVAS_QUATERNION Quaternion; error = IVAS_ERR_OK; st_ivas = hIvasDec->st_ivas; @@ -1077,9 +1101,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC ); *needNewFrame = false; - hSplitBinRend = &st_ivas->hSplitBinRend; + hSplitBinRend = st_ivas->hSplitBinRend; - if ( ( error = ivas_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBitsBuf ) ) != IVAS_ERR_OK ) + if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) { return error; } @@ -1087,13 +1111,14 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && - ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) { numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); numSamplesPerChannelToDecode *= (int16_t) st_ivas->hDecoderConfig->render_framesize; } - if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) { return IVAS_ERR_WRONG_PARAMS; } @@ -1104,10 +1129,17 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( } else { - slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + /* this is needed for OMASA-DISC, because the td-rend granularity is 240 samples at 48kHz, leading to wrong slot count. */ + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + } + else + { + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + } } - /* Decode and render */ if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) { @@ -1133,7 +1165,15 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( } else { - slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + /* this is needed for OMASA-DISC, because the td-rend granularity is 240 samples at 48kHz, leading to wrong slot count. */ + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + } + else + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + } } for ( i = 0; i < BINAURAL_CHANNELS * numPoses; ++i ) @@ -1158,16 +1198,28 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( ro_md_flag = 0; } - if ( ( error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, - st_ivas->hHeadTrackData->Quaternions[0], - st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, - st_ivas->hRenderConfig->split_rend_config.codec, - st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, - hSplitBinRend->hSplitRendBits, - Cldfb_RealBuffer_Binaural, - Cldfb_ImagBuffer_Binaural, - max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) + if ( st_ivas->hHeadTrackData != NULL ) + { + Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; + } + else + { + Quaternion.w = -3.0f; + Quaternion.x = 0.0f; + Quaternion.y = 0.0f; + Quaternion.z = 0.0f; + } + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, + Quaternion, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, + st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + splitRendBits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) { return error; } @@ -1192,11 +1244,10 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( ivas_syn_output( pOutput, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); } - free( st_ivas->hSplitBinRend.hMultiBinCldfbData ); + free( st_ivas->hSplitBinRend->hMultiBinCldfbData ); return error; } -#endif /*---------------------------------------------------------------------* @@ -1206,17 +1257,13 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( *---------------------------------------------------------------------*/ static ivas_error IVAS_DEC_Setup( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ - uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ - uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ - uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ + uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ + uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif ) { ivas_error error; @@ -1252,11 +1299,7 @@ static ivas_error IVAS_DEC_Setup( if ( st_ivas->bfi == 0 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, pcm_type_API_to_internal( pcmType ), data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1265,6 +1308,28 @@ static ivas_error IVAS_DEC_Setup( *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_jbm; *nTcBufferGranularity = (uint16_t) st_ivas->hTcBuffer->n_samples_granularity; *nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + + + /*-----------------------------------------------------------------* + * ISAR: + * - initialize ISAR handle at the first frame + * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) + *-----------------------------------------------------------------*/ + if ( st_ivas->ini_frame == 0 && ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) ) ) + { + if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } } return IVAS_ERR_OK; @@ -1361,13 +1426,9 @@ static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const uint16_t nSamplesForRendering, /* i : number of TC samples wanted from the renderer */ uint16_t *nSamplesRendered, /* o : number of samples rendered */ - uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the renerer pipeline */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf -#else - int16_t *pcmBuf -#endif + uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the renderer pipeline */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf /* o : output synthesis signal */ ) { Decoder_Struct *st_ivas; @@ -1381,11 +1442,7 @@ static ivas_error IVAS_DEC_GetRenderedSamples( st_ivas = hIvasDec->st_ivas; /* run the main IVAS decoding routine */ -#ifdef SPLIT_REND_WITH_HEAD_ROT error = ivas_jbm_dec_render( st_ivas, nSamplesForRendering, nSamplesRendered, nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcmBuf ); -#else - error = ivas_jbm_dec_render( st_ivas, nSamplesForRendering, nSamplesRendered, nSamplesAvailableNext, pcmBuf ); -#endif return error; } @@ -1686,15 +1743,11 @@ ivas_error IVAS_DEC_GetMasaMetadata( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedHeadTrackData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ - IVAS_VECTOR3 Pos, /* i : listener position */ -#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos, /* i : listener position */ const int16_t subframe_idx, /* i : subframe index */ - const IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ -#else - const int16_t subframe_idx /* i : subframe index */ -#endif + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; @@ -1728,9 +1781,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( hHeadTrackData->Pos[subframe_idx].y = Pos.y; hHeadTrackData->Pos[subframe_idx].z = Pos.z; -#ifdef SPLIT_REND_WITH_HEAD_ROT hHeadTrackData->sr_pose_pred_axis = rot_axis; -#endif hIvasDec->updateOrientation = true; return IVAS_ERR_OK; @@ -2041,16 +2092,9 @@ static ivas_error copyRendererConfigStruct( mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; - hRCout->split_rend_config.dof = 3; - hRCout->split_rend_config.hq_mode = 0; - hRCout->split_rend_config.codec_delay_ms = 0; - hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; -#endif + + hRCout->split_rend_config = hRCin->split_rend_config; + hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -2107,9 +2151,7 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error error; -#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) { @@ -2148,22 +2190,60 @@ ivas_error IVAS_DEC_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + /* Re-initialize reverb instance if already available */ + + /* TD renderer Jot reverberator */ + if ( hIvasDec->st_ivas->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* CREND Jot reverberator */ + if ( hIvasDec->st_ivas->hCrendWrapper != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend[0] != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hCrendWrapper->hCrend[0]->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* FB reverberator */ + if ( hIvasDec->st_ivas->hDiracDecBin[0] != NULL && hIvasDec->st_ivas->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ) ); + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* Fastconv CLDFB reverberator */ + if ( hIvasDec->st_ivas->hBinRenderer != NULL && hIvasDec->st_ivas->hBinRenderer->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hBinRenderer->hReverb ) ); + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hBinRenderer->hReverb ), hIvasDec->st_ivas->hHrtfStatistics, hIvasDec->st_ivas->hBinRenderer->conv_band, hIvasDec->st_ivas->hBinRenderer->timeSlots, &( hRenderConfig->roomAcoustics ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); + mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); -#ifdef SPLIT_REND_WITH_HEAD_ROT hRenderConfig->split_rend_config = renderConfig.split_rend_config; /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ if ( hRenderConfig->split_rend_config.dof == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } - if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } -#endif return IVAS_ERR_OK; } @@ -2198,11 +2278,7 @@ ivas_error IVAS_DEC_GetDelay( st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; -#ifdef SPLIT_REND_WITH_HEAD_ROT - nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config ) ); -#else - nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0] ) ); -#endif + nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ); nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); nSamples[0] = nSamples[1] + nSamples[2]; @@ -2474,14 +2550,10 @@ ivas_error IVAS_DEC_TSM_SetQuality( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_VoIP_GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ const uint32_t systemTimestamp_ms /* i : current system timestamp */ #ifdef SUPPORT_JBM_TRACEFILE , @@ -2634,11 +2706,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( /* codec mode to use not known yet - simply output silence */ /* directly set output zero */ int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); -#ifdef SPLIT_REND_WITH_HEAD_ROT set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); -#else - set_s( pcmBuf + nSamplesRendered * nOutChannels, 0, nSamplesToZero * nOutChannels ); -#endif nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesAvailableNext -= nSamplesToZero; @@ -2651,11 +2719,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesToRender = nSamplesPerChannel - nSamplesRendered; /* render IVAS frames directly to the output buffer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2698,13 +2762,9 @@ static void update_voip_rendered20ms( ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif - int16_t *nSamplesFlushed /* o : number of samples flushed */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nSamplesFlushed /* o : number of samples flushed */ ) { ivas_error error; @@ -2719,11 +2779,7 @@ ivas_error IVAS_DEC_Flush( error = IVAS_ERR_OK; if ( nSamplesToRender > 0 && hIvasDec->st_ivas->ivas_format != MONO_FORMAT ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmType, pcmBuf ); -#else - error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); -#endif } else { @@ -2942,7 +2998,6 @@ static ivas_error get_channel_config( { strcpy( str, "Binaural: room with reverb" ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { strcpy( str, "BINAURAL_SPLIT_CODED" ); @@ -2951,7 +3006,6 @@ static ivas_error get_channel_config( { strcpy( str, "Binaural_Split_PCM" ); } -#endif else if ( config == IVAS_AUDIO_CONFIG_EXTERNAL ) { strcpy( str, "External renderer" ); @@ -3083,11 +3137,7 @@ static ivas_error printConfigInfo_dec( get_channel_config( output_config, &config_str[0] ); fprintf( stdout, "Output configuration: %s\n", config_str ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif { fprintf( stdout, "Render framesize: %dms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_framesize ) ); } @@ -3342,6 +3392,7 @@ static ivas_error evs_dec_main( st_ivas->noClipping += #endif ivas_syn_output( p_output, nOutSamples, st_ivas->hDecoderConfig->nchan_out, pcm_buf_local ); + mvs2r( pcm_buf_local, floatBuf, nOutSamples * st_ivas->hDecoderConfig->nchan_out ); } else @@ -3655,36 +3706,31 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitRendBits() + * IVAS_DEC_GetSplitRendBitstreamHeader() * * *---------------------------------------------------------------------*/ -/*! r: decoder error code */ -ivas_error IVAS_DEC_GetSplitRendBits( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structue */ +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL /*|| hIvasDec->st_ivas->hSplitBinRend == NULL */ ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - splitRendBits->bits_buf = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_buf; - splitRendBits->bits_read = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_read; - splitRendBits->bits_written = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_written; - splitRendBits->buf_len = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->buf_len; - splitRendBits->codec = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec; - splitRendBits->pose_correction = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->pose_correction; - splitRendBits->codec_frame_size_ms = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec_frame_size_ms; - - /* data consumed, free it */ - free( hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits ); - hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits = NULL; - + *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; + *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; + *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; return IVAS_ERR_OK; } @@ -3693,10 +3739,9 @@ ivas_error IVAS_DEC_GetSplitRendBits( /*---------------------------------------------------------------------* * IVAS_DEC_GetCldfbSamples() * - * + * API function to output CLDFB samples *---------------------------------------------------------------------*/ -// ToDo: currently unused ivas_error IVAS_DEC_GetCldfbSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ @@ -3705,24 +3750,24 @@ ivas_error IVAS_DEC_GetCldfbSamples( int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ ) { - Decoder_Struct *st_ivas; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - st_ivas = hIvasDec->st_ivas; + hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; num_samples = 0; - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( hSplitBinRend->hCldfbDataOut != NULL ) { - *audio_config = st_ivas->hSplitBinRend.hCldfbDataOut->config; - if ( st_ivas->hSplitBinRend.hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) + *audio_config = hSplitBinRend->hCldfbDataOut->config; + if ( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) { - num_chs = audioCfg2channels( st_ivas->hSplitBinRend.hCldfbDataOut->config ); - maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) { @@ -3730,8 +3775,8 @@ ivas_error IVAS_DEC_GetCldfbSamples( { for ( ch = 0; ch < num_chs; ch++ ) { - *out_real++ = st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; - *out_imag++ = st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; + *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; + *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; } } } @@ -3747,10 +3792,8 @@ ivas_error IVAS_DEC_GetCldfbSamples( return IVAS_ERR_OK; } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * pcm_buffer_offset() * @@ -3777,8 +3820,10 @@ static void *pcm_buffer_offset( } break; default: - return NULL; + break; } + + return NULL; } @@ -3839,4 +3884,294 @@ PCM_RESOLUTION pcm_type_API_to_internal( return pcm_resolution; } -#endif + +/*-------------------------------------------------------------------* + * ivas_create_handle_isar() + * + * Initialize IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static ivas_error ivas_create_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out /* o : ISAR split binaural rendering handle */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + + if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + } + + isar_init_split_rend_handles( &hSplitBinRend->splitrend ); + + hSplitBinRend->hMultiBinCldfbData = NULL; + hSplitBinRend->hCldfbDataOut = NULL; + hSplitBinRend->numTdSamplesPerChannelCached = 0; + + *hSplitBinRend_out = hSplitBinRend; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_destroy_handle_isar() + * + * destroy IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static void ivas_destroy_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */ +) +{ + if ( *hSplitBinRend != NULL ) + { + ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); + + if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + { + free( ( *hSplitBinRend )->hCldfbDataOut ); + ( *hSplitBinRend )->hCldfbDataOut = NULL; + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ + +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *isSplitRend /* o : flag to indicate if split rendering is enabled */ +) +{ + Decoder_Struct *st_ivas; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + *isSplitRend = is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ); + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_dec_reconfig_split_rend() + * + * IVAS decoder split rend reconfig + *-------------------------------------------------------------------*/ + +static ivas_error ivas_dec_reconfig_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; + SPLIT_REND_WRAPPER *hSplitRendWrapper; + + hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + cldfb_in_flag = 1; + } + + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + + isCldfbNeeded = 0; + + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + cldfb_in_flag = 0; + } + + if ( st_ivas->renderer_type != RENDERER_DISABLE ) + { + if ( cldfb_in_flag == 0 ) + { + isCldfbNeeded = 1; + } + else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + { + isCldfbNeeded = 1; + } + else if ( pcm_out_flag && cldfb_in_flag ) + { + isCldfbNeeded = 1; + } + } + else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + isCldfbNeeded = 1; + } + + if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) + { + if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } + + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } + + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) + { + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + } + } + + free( hSplitRendWrapper->hCldfbHandles ); + hSplitRendWrapper->hCldfbHandles = NULL; + } + + if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && + ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && + !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); + } + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_dec_init_split_rend() + * + * IVAS decoder split rend init + *-------------------------------------------------------------------*/ + +static ivas_error ivas_dec_init_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + int16_t cldfb_in_flag, pcm_out_flag; + int16_t mixed_td_cldfb_flag; + + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + cldfb_in_flag = 1; + } + + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + { + if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); + } + } + + mixed_td_cldfb_flag = 0; + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + mixed_td_cldfb_flag = 1; + } + + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag ); + + return error; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_coded_out() + * + * + *---------------------------------------------------------------------*/ + +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *isSplitCoded /* o : flag to indicate if split rendering is enabled */ +) +{ + Decoder_Struct *st_ivas; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + *isSplitCoded = 0; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + *isSplitCoded = 1; + } + + return IVAS_ERR_OK; +} diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index dc7b7dffe8f8c714a3b7be2e7dbbab8e11312b59..e30b2b5eae5e914699fc30032bc137fd9a9bfa72 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -77,14 +77,12 @@ typedef enum _IVAS_DEC_FORCED_REND_MODE } IVAS_DEC_FORCED_REND_MODE; #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT typedef enum _IVAS_DEC_PCM_TYPE { IVAS_DEC_PCM_INT16, IVAS_DEC_PCM_FLOAT, IVAS_DEC_PCM_INVALID } IVAS_DEC_PCM_TYPE; -#endif /* bitstream formats that can be consumed */ @@ -165,29 +163,28 @@ ivas_error IVAS_DEC_FeedFrame_Serial( ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ void *pcmBuf, /* o : output synthesis signal */ -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error IVAS_DEC_GetSplitBinauralBitstream( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); /*! r: decoder error code */ -ivas_error IVAS_DEC_GetSplitRendBits( +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structure */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ ); /*! r: decoder error code */ @@ -198,7 +195,18 @@ ivas_error IVAS_DEC_GetCldfbSamples( IVAS_AUDIO_CONFIG *audio_config, /* o : audio configuration */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ ); -#endif + +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *isSplitRend /* o : flag to indicate if split rendering is enabled */ +); + +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *isSplitCoded /* o : flag to indicate if split rendering is enabled */ +); /*! r: error code */ ivas_error IVAS_DEC_GetObjectMetadata( @@ -220,12 +228,8 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 Pos, /* i : listener position */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t subframe_idx, /* i : subframe index */ - IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ -#else - const int16_t subframe_idx /* i : subframe index */ -#endif + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ ); /*! r: error code */ @@ -278,12 +282,8 @@ ivas_error IVAS_DEC_TSM_SetQuality( ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ const uint32_t systemTimestamp_ms /* i : current system timestamp */ #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, @@ -294,12 +294,8 @@ ivas_error IVAS_DEC_VoIP_GetSamples( ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ int16_t *nSamplesFlushed /* o : number of samples flushed */ ); @@ -312,12 +308,10 @@ ivas_error IVAS_DEC_EnableVoIP( const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT /*! r: error code */ ivas_error IVAS_DEC_EnableSplitRendering( IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ ); -#endif ivas_error IVAS_DEC_SetRenderFramesize( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index be39e263b904b27eae16ba70a5bba8e0a3c99379..b58f208b4c6b10986f54754d4584be6587f338e1 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -446,7 +446,7 @@ ivas_error ivas_corecoder_enc_reconfig( } else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) { - if ( ( error = mct_enc_reconfigure( st_ivas, st_ivas->nchan_transport != nchan_transport_old ) ) != IVAS_ERR_OK ) + if ( ( error = mct_enc_reconfigure( st_ivas, nchan_transport_old_real != nchan_transport_real ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index f971fcbe677a18e739bb31b8173dfbd0f14bd8fc..a3119193c7216bc42d9413996db37302dc163532 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -600,6 +600,14 @@ ivas_error ivas_cpe_enc( if ( sts[0]->core_brate == SID_2k40 ) { ivas_write_format_sid( ivas_format, hCPE->element_mode, sts[0]->hBstr ); + if ( ivas_format == SBA_FORMAT ) + { + /* Write SBA planar flag */ + push_indice( sts[0]->hBstr, IND_SMODE, st_ivas->hEncoderConfig->sba_planar, SBA_PLANAR_BITS ); + + /* Write SBA order */ + push_indice( sts[0]->hBstr, IND_SMODE, st_ivas->hEncoderConfig->sba_order, SBA_ORDER_BITS ); + } } /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 3146d8ad9bbd51559c68bb96bee670202cf847c2..75e0ec27f710a27f8c6e5eea34e273faa6899ae9 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -291,6 +291,7 @@ ivas_error ivas_dirac_enc( const int16_t input_frame, /* i : input frame length */ const int16_t dtx_vad, /* i : DTX vad flag */ const IVAS_FORMAT ivas_format, /* i : ivas format */ + const int16_t nchan_transport, /* i : number of transport channels */ const int16_t hodirac_flag /* i : hodirac flag */ ) { @@ -367,7 +368,7 @@ ivas_error ivas_dirac_enc( push_next_indice( hMetaData, 1, 1 ); /* encode SID parameters */ - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, nchan_transport, SBA_FORMAT ); } for ( b = hQMetaData->q_direction->cfg.start_band; b < hQMetaData->q_direction->cfg.nbands; b++ ) diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index a394f1609011619c4f1f25eea95279f8646622f2..a24007b21ae36cd4248dca34ba8f6705c3a6afbf 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -674,10 +674,7 @@ ivas_error ivas_init_encoder( { st_ivas->ism_mode = ISM_MODE_NONE; - if ( ivas_total_brate >= IVAS_256k ) - { - st_ivas->ism_mode = ISM_SBA_MODE_DISC; - } + st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism ); if ( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) { @@ -732,8 +729,13 @@ ivas_error ivas_init_encoder( else { /* allocate and initialize MCT core coder */ - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; + { + int16_t n_all; + + n_all = st_ivas->nchan_transport + st_ivas->hEncoderConfig->nchan_ism; + st_ivas->nCPE = ( n_all + 1 ) >> 1; + } 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 ) diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index e4b536dbee95fdf5c3c1f8e9064d86b5312e184e..54691e864e63e6cc5b2af98591b2616953961814 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -420,14 +420,15 @@ ivas_error ivas_masa_encode( { if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MODE_NONE ) { - /* use the MASA number of transport channels bit to signal if there are 3 or 4 objects */ - if ( nchan_ism == 4 ) + /* use the MASA number of transport channels bit to signal if there are 1 or 2 objects */ + if ( nchan_ism == 1 || nchan_ism == 2 ) { - push_next_indice( hMetaData, 1, MASA_TRANSP_BITS ); + push_next_indice( hMetaData, nchan_ism - 1, MASA_TRANSP_BITS ); } else { - push_next_indice( hMetaData, 0, MASA_TRANSP_BITS ); + /* for 3 or 4 objects write already the number of MASA directions */ + push_next_indice( hMetaData, hQMetaData->no_directions - 1, MASA_TRANSP_BITS ); } } else @@ -440,13 +441,13 @@ ivas_error ivas_masa_encode( if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MODE_NONE ) { - if ( nchan_ism <= 3 ) + if ( nchan_ism >= 3 ) /* if 3 or 4 objects */ { - push_next_indice( hMetaData, nchan_ism, MASA_HEADER_BITS ); + push_next_indice( hMetaData, 5 - nchan_ism, MASA_HEADER_BITS ); } else { - push_next_indice( hMetaData, nchan_ism - 1, MASA_HEADER_BITS ); + push_next_indice( hMetaData, 3, MASA_HEADER_BITS ); } hQMetaData->metadata_max_bits -= MASA_HEADER_BITS; } @@ -457,10 +458,12 @@ ivas_error ivas_masa_encode( push_next_indice( hMetaData, 0, MASA_HEADER_BITS ); hQMetaData->metadata_max_bits -= MASA_HEADER_BITS; } - /* write number of directions */ - push_next_indice( hMetaData, hQMetaData->no_directions - 1, 1 ); - hQMetaData->metadata_max_bits -= 1; - + if ( !( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MODE_NONE && nchan_ism > 2 ) ) + { + /* write number of directions */ + push_next_indice( hMetaData, hQMetaData->no_directions - 1, 1 ); + hQMetaData->metadata_max_bits -= 1; + } /* write subframe mode */ push_next_indice( hMetaData, hQMetaData->q_direction[0].cfg.nblocks == 1 ? 1 : 0, MASA_SUBFRAME_BITS ); hQMetaData->metadata_max_bits -= MASA_SUBFRAME_BITS; @@ -596,7 +599,7 @@ ivas_error ivas_masa_encode( free( h_orig_metadata ); - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, ivas_format ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, 0, ivas_format ); /* restore old values */ hMasa->config.numCodingBands = numCodingBands; diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 8705d94c64ab5562916c9ce9cdf7c63b27919ac6..cf2f3d8afd28a0848dfc59db79bf6ba2ca4b77be 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -497,7 +497,9 @@ void ivas_mct_core_enc( { nAvailBits -= IVAS_FORMAT_SIGNALING_NBITS_EXTENDED; nAvailBits -= SBA_ORDER_BITS + SBA_PLANAR_BITS; - if ( ivas_format == SBA_ISM_FORMAT && nChannels > 4 ) + + /*MCT is used at bitrates > 80 kbps and additional 1 bit is present at these bitrates*/ + if ( ivas_format == SBA_ISM_FORMAT ) { nAvailBits -= IVAS_COMBINED_FORMAT_SIGNALLING_BITS; } @@ -574,7 +576,9 @@ void ivas_mct_core_enc( #ifdef DEBUGGING format_bits = ( ivas_format == MC_FORMAT ? IVAS_FORMAT_SIGNALING_NBITS + MC_LS_SETUP_BITS : IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + SBA_ORDER_BITS + SBA_PLANAR_BITS ); - format_bits += ( ivas_format == SBA_ISM_FORMAT && nChannels > FOA_CHANNELS ); + + format_bits += ( ivas_format == SBA_ISM_FORMAT ); + mct_bits += hMCT->nBitsMCT + hMCT->nchan_out_woLFE; assert( ( total_brate + ( NBITS_BWIDTH + format_bits + mct_bits + sba_meta + lfe_bits ) * FRAMES_PER_SEC ) == ivas_total_brate ); #endif diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index a2b857b9d8558a72b5bbc8ed74de1a8d864f9bcb..b00396bfab311a4b0f18a85aae8efadb19bff3b5 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -182,9 +182,11 @@ ivas_error ivas_osba_enc_reconfig( ivas_error error; ENCODER_CONFIG_HANDLE hEncoderConfig; + error = IVAS_ERR_OK; hEncoderConfig = st_ivas->hEncoderConfig; ivas_total_brate = hEncoderConfig->ivas_total_brate; + int16_t nchan_transport; if ( ivas_total_brate != hEncoderConfig->last_ivas_total_brate ) { @@ -197,17 +199,11 @@ ivas_error ivas_osba_enc_reconfig( spar_reconfig_flag = 0; old_ism_mode = st_ivas->ism_mode; - if ( ivas_total_brate >= IVAS_256k ) - { - st_ivas->ism_mode = ISM_SBA_MODE_DISC; - } - else - { - st_ivas->ism_mode = ISM_MODE_NONE; - } + st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism ); 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, hEncoderConfig->sba_order ); analysis_order_old = ivas_sba_get_analysis_order( hEncoderConfig->last_ivas_total_brate, hEncoderConfig->sba_order ); nbands_old = st_ivas->hQMetaData->q_direction->cfg.nbands; @@ -334,20 +330,25 @@ ivas_error ivas_osba_enc_reconfig( * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ + nchan_transport = st_ivas->nchan_transport; if ( old_ism_mode == ISM_MODE_NONE && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; + { + nchan_transport = st_ivas->nchan_transport + st_ivas->hEncoderConfig->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; + } } else if ( old_ism_mode == ISM_SBA_MODE_DISC && st_ivas->ism_mode == ISM_MODE_NONE ) { + nchan_transport_old += st_ivas->hEncoderConfig->nchan_ism; + nchan_transport = st_ivas->nchan_transport; } else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; - nCPE_old = st_ivas->nCPE; - nchan_transport_old = st_ivas->nchan_transport; nchan_transport_old += st_ivas->hEncoderConfig->nchan_ism; + nchan_transport = st_ivas->nchan_transport + st_ivas->hEncoderConfig->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; } if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, ivas_total_brate / st_ivas->nchan_transport, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE ) ) != IVAS_ERR_OK ) diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index a875f14771f5cf4f91bcaa9483b7aaa592f416fc..1260e115dc6a17e693664467a80fc7d04f508ca4 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -955,6 +955,7 @@ void ivas_qmetadata_enc_sid_encode( BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ IVAS_QMETADATA *q_metadata, /* i/o: metadata handle */ const int16_t masa_sid_descriptor, /* i : description of MASA SID coding structure */ + const int16_t nchan_transport, /* i : number of transport channels */ const int16_t ivas_format /* i : IVAS format */ ) { @@ -968,10 +969,12 @@ void ivas_qmetadata_enc_sid_encode( float avg_elevation[MASA_MAXIMUM_CODING_SUBBANDS]; int16_t bits_dir, bits_diff, bits_delta; int16_t metadata_sid_bits; /* bits allocated to SID for metadata */ + int16_t sba_spar_bitlen; if ( ivas_format == SBA_FORMAT ) { - metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 2 - SID_FORMAT_NBITS; /* -1 for inactive mode header bit*/ + sba_spar_bitlen = ivas_sba_spar_sid_bitlen( nchan_transport ); + metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - sba_spar_bitlen - SID_FORMAT_NBITS - SBA_ORDER_BITS - SBA_PLANAR_BITS - 1; /* -1 for inactive mode header bit*/ } else { @@ -1250,7 +1253,7 @@ void reset_metadata_spatial( assert( hMetaData->ind_list[0].nb_bits == 1 ); #endif hMetaData->ind_list[0].value = 1; - metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; + metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - SBA_PLANAR_BITS - SBA_ORDER_BITS; while ( hMetaData->nb_bits_tot < metadata_sid_bits ) { diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 215b977f25b6d82e1011c9cbd275c68f7969354e..e1355c1b7a81ed2f138e76a41f9d87fce5ac0e29 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -224,6 +224,14 @@ ivas_error ivas_sce_enc( if ( st->core_brate == SID_2k40 ) { ivas_write_format_sid( ivas_format, IVAS_SCE, st->hBstr ); + if ( ivas_format == SBA_FORMAT ) + { + /* Write SBA planar flag */ + push_indice( st->hBstr, IND_SMODE, st_ivas->hEncoderConfig->sba_planar, SBA_PLANAR_BITS ); + + /* Write SBA order */ + push_indice( st->hBstr, IND_SMODE, st_ivas->hEncoderConfig->sba_order, SBA_ORDER_BITS ); + } } /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index d3ff38062aa496c10ea462c3b966f7b876a9276e..a74a7f6587e8414714069892f1357db28b240595 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -354,11 +354,17 @@ ivas_error ivas_spar_enc( /* Write SBA planar flag */ push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_planar, SBA_PLANAR_BITS ); - /* hack to indicate OSBA bitstream at VLBR */ + /* hack to indicate OSBA format (SBA order = 0) at low bitrates */ push_indice( st0->hBstr, IND_SMODE, 0, SBA_ORDER_BITS ); + + /* additionally code the real SBA order */ + push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_order, SBA_ORDER_BITS ); } else { + /* Write SBA planar flag */ + push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_planar, SBA_PLANAR_BITS ); + /* Write SBA order */ push_indice( st0->hBstr, IND_SMODE, hEncoderConfig->sba_order, SBA_ORDER_BITS ); } @@ -689,11 +695,12 @@ static ivas_error ivas_spar_enc_process( hodirac_flag = ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ); - if ( ( error = ivas_dirac_enc( st_ivas->hDirAC, hQMetaData, hMetaData, data_f, ppIn_FR_real, ppIn_FR_imag, input_frame, dtx_vad, hEncoderConfig->ivas_format, hodirac_flag ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_enc( st_ivas->hDirAC, hQMetaData, hMetaData, data_f, ppIn_FR_real, ppIn_FR_imag, input_frame, dtx_vad, hEncoderConfig->ivas_format, nchan_transport, hodirac_flag ) ) != IVAS_ERR_OK ) { return error; } + /* Set Energy Ratio to 0.0 if the mono flag has been set */ if ( hQMetaData->dirac_mono_flag ) { diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index cb44858d7da5016fe255c22cc6fc481952540f68..a259670f71b2b38134c8f8425daeeac78c799c3d 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -1716,6 +1716,7 @@ static void ivas_write_parameter_bitstream_dtx( int16_t idx; float pr_min_max[2]; int16_t zero_pad_bits, sid_bits_len; + int16_t sba_spar_bitlen; sid_bits_len = hMetaData->nb_bits_tot; pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; @@ -1771,7 +1772,8 @@ static void ivas_write_parameter_bitstream_dtx( } sid_bits_len = hMetaData->nb_bits_tot - sid_bits_len; - zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; + sba_spar_bitlen = ivas_sba_spar_sid_bitlen( num_dmx[0] ); + zero_pad_bits = sba_spar_bitlen - sid_bits_len; assert( zero_pad_bits >= 0 ); if ( num_dmx[0] == 2 ) { diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 03d16c98e2dcd389e084e23efc41de66d7d734ac..68b37bab7dbe670950903ea61a9760d5421b1404 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1072,11 +1072,7 @@ ivas_error IVAS_ENC_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL, IVAS_AUDIO_CONFIG_INVALID ) ); -#else - *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); -#endif + *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL, 0 ) ); *delay *= hEncoderConfig->nchan_inp; diff --git a/lib_rend/ivas_MSPred.c b/lib_isar/isar_MSPred.c similarity index 98% rename from lib_rend/ivas_MSPred.c rename to lib_isar/isar_MSPred.c index 3986526c45b596a094f44a1f3cb0583295ab90b0..50efa285d1f6b87d06c07a0a8673c0ee5ce71d20 100644 --- a/lib_rend/ivas_MSPred.c +++ b/lib_isar/isar_MSPred.c @@ -32,10 +32,8 @@ #include "options.h" #include -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_lcld_rom_tables.h" -#include "ivas_lcld_prot.h" -#include "ivas_prot_rend.h" +#include "isar_lcld_prot.h" +#include "isar_prot.h" #include "wmc_auto.h" @@ -73,16 +71,16 @@ int32_t quantPhase( /*-------------------------------------------------------------------* - * Function cplxmult() + * Function cplxmult_lcld() * * *-------------------------------------------------------------------*/ -void cplxmult( +void cplxmult_lcld( float *pr1, float *pi1, - float r2, - float i2 ) + const float r2, + const float i2 ) { float r1 = *pr1, i1 = *pi1; @@ -468,4 +466,3 @@ void writeMSPred( return; } #endif -#endif diff --git a/lib_rend/ivas_NoiseGen.c b/lib_isar/isar_NoiseGen.c similarity index 96% rename from lib_rend/ivas_NoiseGen.c rename to lib_isar/isar_NoiseGen.c index 846a49a7871bb43321d29d7bb331d229e8a8f0ca..27d82994a2334b468c95e1b29334a6bad0f2637f 100644 --- a/lib_rend/ivas_NoiseGen.c +++ b/lib_isar/isar_NoiseGen.c @@ -32,11 +32,9 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" -#include "ivas_lcld_prot.h" -#include "ivas_prot_rend.h" +#include "isar_lcld_prot.h" #include "wmc_auto.h" @@ -55,4 +53,3 @@ void DeleteNoiseGen( NoiseGen *psNoiseGen ) } extern float GetNoise( NoiseGen *psNoiseGen ); -#endif diff --git a/lib_rend/ivas_PerceptualModel.c b/lib_isar/isar_PerceptualModel.c similarity index 96% rename from lib_rend/ivas_PerceptualModel.c rename to lib_isar/isar_PerceptualModel.c index 7c2be648032b0638b3f8d030c9028ce5f0316399..d1e658c8ef4c18b5482e1b956a7858621652ddb5 100644 --- a/lib_rend/ivas_PerceptualModel.c +++ b/lib_isar/isar_PerceptualModel.c @@ -32,11 +32,9 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_lcld_prot.h" +#include "isar_lcld_prot.h" #include "prot.h" -#include "ivas_prot_rend.h" -#include "ivas_lcld_rom_tables.h" +#include "isar_rom_lcld_tables.h" #include #include "wmc_auto.h" @@ -46,7 +44,6 @@ *------------------------------------------------------------------------------------------*/ #define PERCEPTUAL_MODEL_SCALE ( 64 ) -#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 ) #define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 ) #define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 ) #define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 ) @@ -103,7 +100,6 @@ void PerceptualModel( /* Calculate sensation level offset */ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; - // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; /* Offset envelope by sensation level offset */ piExcitation[n] -= iSLOffset; @@ -168,7 +164,6 @@ void PerceptualModelStereo( /* Calculate sensation level offset */ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; - // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; /* Offset envelope by sensation level offset */ piExcitation0[n] -= iSLOffset; @@ -205,7 +200,6 @@ void PerceptualModelStereo( /* Calculate sensation level offset */ iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; - // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; /* Offset envelope by sensation level offset */ piExcitation1[n] -= iSLOffset; @@ -254,4 +248,3 @@ void PerceptualModelStereo( return; } -#endif diff --git a/lib_rend/ivas_PredDecoder.c b/lib_isar/isar_PredDecoder.c similarity index 71% rename from lib_rend/ivas_PredDecoder.c rename to lib_isar/isar_PredDecoder.c index ce791e93291b12d5f4034fcf111172137040126d..e1a46f9dbd3bd0da996ab4a6f48553e91a842d2a 100644 --- a/lib_rend/ivas_PredDecoder.c +++ b/lib_isar/isar_PredDecoder.c @@ -32,14 +32,14 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" -#include "ivas_prot_rend.h" -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" +#include "isar_prot.h" +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" #include "wmc_auto.h" + /*-------------------------------------------------------------------* * Function CreatePredictionDecoder() * @@ -64,6 +64,44 @@ ivas_error CreatePredictionDecoder( psPredictionDecoder->iNumBlocks = iNumBlocks; psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; psPredictionDecoder->iSubSetId = 0; + + /* PLC_IMPROVEMENT */ + if ( ( psPredictionDecoder->ppiDecodingFailedPrev = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppiDecodingFailed = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppiDecodingUnresolved = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + if ( ( psPredictionDecoder->ppiDecodingUnresolved[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppiDecodingFailed[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppiDecodingFailedPrev[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_MAX_NUM_PRED_SUBSETS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + for ( k = 0; k < LCLD_MAX_NUM_PRED_SUBSETS; k++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[n][k] = 0; + psPredictionDecoder->ppiDecodingFailed[n][k] = 0; + psPredictionDecoder->ppiDecodingFailedPrev[n][k] = 0; + } + } + if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -182,6 +220,10 @@ void DeletePredictionDecoder( free( psPredictionDecoder->ppiA1Phase[n] ); free( psPredictionDecoder->ppfPredStateReal[n] ); free( psPredictionDecoder->ppfPredStateImag[n] ); + /* PLC_IMPROVEMENT */ + free( psPredictionDecoder->ppiDecodingUnresolved[n] ); + free( psPredictionDecoder->ppiDecodingFailed[n] ); + free( psPredictionDecoder->ppiDecodingFailedPrev[n] ); } free( psPredictionDecoder->piPredChanEnable ); free( psPredictionDecoder->ppiPredBandEnable ); @@ -191,6 +233,10 @@ void DeletePredictionDecoder( free( psPredictionDecoder->ppiA1Phase ); free( psPredictionDecoder->ppfPredStateReal ); free( psPredictionDecoder->ppfPredStateImag ); + /* PLC_IMPROVEMENT */ + free( psPredictionDecoder->ppiDecodingUnresolved ); + free( psPredictionDecoder->ppiDecodingFailed ); + free( psPredictionDecoder->ppiDecodingFailedPrev ); free( psPredictionDecoder ); psPredictionDecoder = NULL; @@ -198,15 +244,16 @@ void DeletePredictionDecoder( return; } + /*-------------------------------------------------------------------* * Function ReadPredictors() * * *-------------------------------------------------------------------*/ -int32_t ReadPredictors( +int16_t ReadPredictors( PredictionDecoder *psPredictionDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int16_t iBitsRead = 0; int32_t c; @@ -214,12 +261,12 @@ int32_t ReadPredictors( int16_t iNumPredBandBits = 6; const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); - psPredictionDecoder->iNumSubSets = ivas_split_rend_bitstream_read_int32( pBits, iSubSetBits ) + 1; + psPredictionDecoder->iNumSubSets = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ) + 1; iBitsRead += iSubSetBits; if ( psPredictionDecoder->iNumSubSets > 1 ) { - psPredictionDecoder->iSubSetId = ivas_split_rend_bitstream_read_int32( pBits, iSubSetBits ); + psPredictionDecoder->iSubSetId = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ); iBitsRead += iSubSetBits; iNumPredBandBits = ( psPredictionDecoder->iNumSubSets >= 4 ? 4 : 5 ); } @@ -227,9 +274,10 @@ int32_t ReadPredictors( { psPredictionDecoder->iSubSetId = 0; } + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { - psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); + psPredictionDecoder->piPredChanEnable[c] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); iBitsRead += (int16_t) psPredictionDecoder->iNumSubSets; if ( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) @@ -242,13 +290,13 @@ int32_t ReadPredictors( { psPredictionDecoder->ppiPredBandEnable[c][b] = 0; } - iNumPredBands = ivas_split_rend_bitstream_read_int32( pBits, iNumPredBandBits ); + iNumPredBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iNumPredBandBits ); iBitsRead += iNumPredBandBits; iNumPredBands = iNumPredBands * psPredictionDecoder->iNumSubSets + b0; for ( b = b0; b < iNumPredBands; b += bstep ) { - psPredictionDecoder->ppiPredBandEnable[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + psPredictionDecoder->ppiPredBandEnable[c][b] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) @@ -257,9 +305,9 @@ int32_t ReadPredictors( int32_t iA1Phase; float fA1Real; float fA1Imag; - iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + iA1Mag = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; - iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); + iA1Phase = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; @@ -294,6 +342,109 @@ int32_t ReadPredictors( return iBitsRead; } + +/*-------------------------------------------------------------------* + * Function SetDecodingPassed() + * + * + *-------------------------------------------------------------------*/ + +void SetDecodingPassed( + PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailed[ch][n] = 0; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function AnyDecodingUnresolved() + * + * + *-------------------------------------------------------------------*/ + +int32_t AnyDecodingUnresolved( + PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingUnresolved[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + + +/*-------------------------------------------------------------------* + * Function UpdateDecodingFailedStatus() + * + * + *-------------------------------------------------------------------*/ + +void UpdateDecodingFailedStatus( + PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = psPredictionDecoder->ppiDecodingFailed[ch][n]; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function UpdateDecodingUnresolved() + * + * + *-------------------------------------------------------------------*/ + +void UpdateDecodingUnresolved( + PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + + int32_t iCurrentSubSet = psPredictionDecoder->iSubSetId; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + /* Prediction data always available for current subset */ + psPredictionDecoder->ppiDecodingUnresolved[ch][iCurrentSubSet] = 0; + + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + int32_t iSubSetActive = get_bit( psPredictionDecoder->piPredChanEnable[ch], n ); + if ( iSubSetActive == 0 ) + { + /* Prediction information available inactive subsets (e.g. no Prediction) */ + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 0; + } + } + } + + return; +} + + /*-------------------------------------------------------------------* * Function ApplyInversePredictors() * @@ -306,6 +457,7 @@ void ApplyInversePredictors( float ***pppfImag ) { int32_t c; + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { if ( psPredictionDecoder->piPredChanEnable[c] > 0 ) @@ -353,4 +505,3 @@ void ApplyInversePredictors( return; } -#endif diff --git a/lib_rend/ivas_PredEncoder.c b/lib_isar/isar_PredEncoder.c similarity index 85% rename from lib_rend/ivas_PredEncoder.c rename to lib_isar/isar_PredEncoder.c index 50ac5524fb57bf39e81531790301d6e736a2dfa4..5d8b9d59e1b4173800bcf64a1cd2f0b178793bc9 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_isar/isar_PredEncoder.c @@ -32,12 +32,11 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" #include "prot.h" -#include "ivas_prot_rend.h" +#include "isar_prot.h" #include "wmc_auto.h" @@ -46,13 +45,17 @@ * * *-------------------------------------------------------------------*/ + static void activate_bit( int32_t *state, const int32_t bit_id ) { ( *state ) |= ( 1 << bit_id ); + + return; } + /*-------------------------------------------------------------------* * Function deactivate_bit() * @@ -64,8 +67,29 @@ static void deactivate_bit( const int32_t bit_id ) { ( *state ) &= ( ~( 1 << bit_id ) ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function UpdatePredictionSubSetId() + * + * + *-------------------------------------------------------------------*/ + +void UpdatePredictionSubSetId( + PredictionEncoder *psPredictionEncoder ) +{ + if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) + { + psPredictionEncoder->iSubSetId = 0; + } + + return; } + /*-------------------------------------------------------------------* * Function CreatePredictionEncoder() * @@ -92,16 +116,6 @@ ivas_error CreatePredictionEncoder( psPredictionEncoder->iSubSetId = 0; psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; psPredictionEncoder->iNumSubSets = iNumSubSets; - if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * LCLD_PRED_WIN_LEN ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - - for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) - { - psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) LCLD_PRED_WIN_LEN ); - } - if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { @@ -115,7 +129,7 @@ ivas_error CreatePredictionEncoder( for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { psPredictionEncoder->piPredChanEnable[n] = 0; - psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly + psPredictionEncoder->piNumPredBands[n] = 40; } if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) @@ -271,9 +285,6 @@ void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ) { int32_t n; - - free( psPredictionEncoder->pfWindow ); - for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { int32_t k; @@ -367,8 +378,7 @@ void ComputePredictors( for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) { int32_t b; - psPredictionEncoder->piNumPredBands[c] = min( 50, psPredictionEncoder->iMaxNumPredBands ); - for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += bstep ) + for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) { int32_t n; float fGain = 0.0; @@ -418,7 +428,7 @@ void ComputePredictors( /* compute these before quant */ /* Compute est coding gain based on quantized filter coefficients */ fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); fA1Mag = fMagScale * asinf( fA1Mag ); iA1Mag = (int32_t) ( fA1Mag + 0.5f ); @@ -430,14 +440,14 @@ void ComputePredictors( fA1Phase = fPhaseScale * fA1Phase; iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f ); iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; - iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; fA1Phase = fInvPhaseScale * (float) iA1Phase; fA1Real = fA1Mag * cosf( fA1Phase ); fA1Imag = fA1Mag * sinf( fA1Phase ); fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); fGain = ( fGain < fGain2 ) ? fGain : fGain2; fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; } @@ -447,11 +457,11 @@ void ComputePredictors( fA1Imag = 0.0f; iA1Mag = 0; iA1Phase = 0; - fGain = -10.0f; // Fix this + fGain = -10.0f; } pfEstPredBitGain[b] = fBitGain; - psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); // Initial prediction enable + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); psPredictionEncoder->ppfA1Real[c][b] = fA1Real; psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; @@ -467,8 +477,8 @@ void ComputePredictors( fBestCost = 0.0; iPredBands = 0; fBitGain = -7.0; - for ( b = b0; b < 50; b += bstep ) - { // still getting this decision wrong! + for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { fBitGain -= 1.0; if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) { @@ -491,15 +501,6 @@ void ComputePredictors( activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep; } - else if ( iPredBands > 0 ) - { - for ( b = iPredBands; b < LCLD_BANDS; b += bstep ) - { - psPredictionEncoder->ppiPredBandEnable[c][b] = 0; - } - activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); - psPredictionEncoder->piNumPredBands[c] = iPredBands; - } else { for ( b = b0; b < LCLD_BANDS; b += bstep ) @@ -511,6 +512,8 @@ void ComputePredictors( } } } + + return; } @@ -520,61 +523,6 @@ void ComputePredictors( * *-------------------------------------------------------------------*/ -void ApplyForwardPredictors( - PredictionEncoder *psPredictionEncoder, - float ***pppfReal, - float ***pppfImag ) -{ - int32_t c; - for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) - { - int32_t b; - if ( psPredictionEncoder->piPredChanEnable[c] > 0 ) - { - for ( b = 0; b < LCLD_BANDS; b++ ) - { - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) - { - int32_t n; - float fOldReal = 0.0f; - float fOldImag = 0.0f; - float fA1Real; - float fA1Imag; - - int32_t iSubset = b % psPredictionEncoder->iNumSubSets; - if ( iSubset != psPredictionEncoder->iSubSetId ) - { - fOldReal = psPredictionEncoder->ppfInpPrevReal[c][b]; - fOldImag = psPredictionEncoder->ppfInpPrevImag[c][b]; - } - psPredictionEncoder->ppfInpPrevReal[c][b] = pppfReal[c][psPredictionEncoder->iNumBlocks - 1][b]; - psPredictionEncoder->ppfInpPrevImag[c][b] = pppfImag[c][psPredictionEncoder->iNumBlocks - 1][b]; - - fA1Real = psPredictionEncoder->ppfA1Real[c][b]; - fA1Imag = psPredictionEncoder->ppfA1Imag[c][b]; - for ( n = 0; n < psPredictionEncoder->iNumBlocks; n++ ) - { - float fReal; - float fImag; - - fReal = pppfReal[c][n][b] + fA1Real * fOldReal - fA1Imag * fOldImag; - fImag = pppfImag[c][n][b] + fA1Real * fOldImag + fA1Imag * fOldReal; - - fOldReal = pppfReal[c][n][b]; - fOldImag = pppfImag[c][n][b]; - - pppfReal[c][n][b] = fReal; - pppfImag[c][n][b] = fImag; - } - } - } - } - } - - return; -} - - /*-------------------------------------------------------------------* * Function WritePredictors() * @@ -583,7 +531,7 @@ void ApplyForwardPredictors( int32_t WritePredictors( PredictionEncoder *psPredictionEncoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsWritten = 0; int32_t c; @@ -593,13 +541,13 @@ int32_t WritePredictors( const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); /* number of subsets */ - ivas_split_rend_bitstream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */ + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */ iBitsWritten += iSubSetBits; if ( iNumSubSets > 1 ) { /* write current subset */ - ivas_split_rend_bitstream_write_int32( pBits, iSubSetId, iSubSetBits ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iSubSetId, iSubSetBits ); iBitsWritten += iSubSetBits; iNumPredBandBits = ( iNumSubSets >= 4 ? 4 : 5 ); } @@ -609,19 +557,19 @@ int32_t WritePredictors( int32_t b; int32_t b0 = iSubSetId; - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); iBitsWritten += iNumSubSets; if ( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) { int32_t iNumPredBands = ( psPredictionEncoder->piNumPredBands[c] - b0 ) / iNumSubSets; - ivas_split_rend_bitstream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); iBitsWritten += iNumPredBandBits; for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) { - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); iBitsWritten += 1; if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) @@ -632,10 +580,10 @@ int32_t WritePredictors( iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; - ivas_split_rend_bitstream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; - ivas_split_rend_bitstream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; } } @@ -644,4 +592,3 @@ int32_t WritePredictors( return iBitsWritten; } -#endif diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_isar/isar_RMSEnvGrouping.c similarity index 97% rename from lib_rend/ivas_RMSEnvGrouping.c rename to lib_isar/isar_RMSEnvGrouping.c index b67b8c1f757d261abe3bb53c7c2061bd32402bd9..0ef4e99a0ffc96ded88fb9148abdd4f1bf7489ca 100644 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ b/lib_isar/isar_RMSEnvGrouping.c @@ -30,16 +30,12 @@ *******************************************************************************************************/ -/* Double check cost function calculation */ - #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" -#include "ivas_prot_rend.h" -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" #include "wmc_auto.h" @@ -244,7 +240,7 @@ static void ComputeBandEnergy( fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] ); iFBOffset++; } - fEnergy /= (float) ( piBandwidths[b] ); // Correction removed normalization by 2 + fEnergy /= (float) ( piBandwidths[b] ); /* Correction removed normalization by 2*/ ppfBandEnergy[k][iChanOffset + b] = fEnergy; fWeight = 0.33f * powf( 10.0f, 0.0068f * ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) ); @@ -309,7 +305,7 @@ static void ComputeMergeRMS( fRMSEnvelope = log2f( fGroupEnergy ); iQRMSEnvelope = ( fRMSEnvelope > 0.0 ) ? (int32_t) ( fRMSEnvelope + 0.5 ) : (int32_t) ( fRMSEnvelope - 0.5 ); - fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; + fGroupEnergy = 10.0f * log10f( fGroupEnergy ); /* Note epsilon was added when computing BandEnergy;*/ pfMergedEnergydB[b] = fGroupEnergy; piQRMSEnvelope[b] = iQRMSEnvelope; @@ -398,7 +394,7 @@ static float ComputeSNRPenalty( fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b]; if ( fDeltadB < -9.0309f ) { - fSNRPenalty += 1e10f; // Some large number to prevent clipping + fSNRPenalty += 1e10f; /* Some large number to prevent clipping*/ } else /*if(fDeltadB < 0.0)*/ { @@ -541,7 +537,7 @@ static void ComputeGreedyGroups3( } else { - iDone++; // This only catches a problem + iDone++; /* This only catches a problem*/ } } @@ -590,7 +586,7 @@ static void ComputeRMSEnvelope( fGroupEnergy /= (float) piGroupLengths[k]; fGroupEnergy = log2f( fGroupEnergy ); - pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 ); // Bug fix + pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 ); pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] > ENV_MIN ) ? pppiRMSEnvelope[n][k][b] : ENV_MIN; pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] < ENV_MAX ) ? pppiRMSEnvelope[n][k][b] : ENV_MAX; } @@ -668,7 +664,7 @@ void ComputeEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, const int32_t iChannels, const int32_t iNumBands, - const int32_t *piBandwidths, // pass in absolute thresh + const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piNumGroups, @@ -727,4 +723,3 @@ void ComputeEnvelopeGrouping( return; } -#endif diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h new file mode 100644 index 0000000000000000000000000000000000000000..7a2a2a1698aad9c8060a3f0176acd40e618a243f --- /dev/null +++ b/lib_isar/isar_cnst.h @@ -0,0 +1,127 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_CNST_H +#define ISAR_CNST_H + +#include +#include "options.h" + +/* clang-format off */ + + +/*----------------------------------------------------------------------------------* + * Split Binaural Rendering Constants + *----------------------------------------------------------------------------------*/ + +typedef enum +{ + PCM_INT16, + PCM_FLOAT32, + PCM_NOT_KNOW = 0xffff +} PCM_RESOLUTION; + +typedef enum +{ + ANY_YAW, + PITCH_ONLY, + ANY_ROLL, + PRED_ONLY, + PRED_ROLL_ONLY, + COM_GAIN_ONLY, + LR_GAIN_ONLY +} ISAR_SPLIT_REND_POSE_TYPE; + + +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ + +#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 +#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 +#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 +#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 +#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ + +#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES ) +#define MAX_SPLIT_REND_MD_BANDS 20 +#define MAX_SPLIT_MD_SUBFRAMES 1 +#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS +#define COMPLEX_MD_BAND_THRESH_LOW 4 +#define COMPLEX_MD_BAND_THRESH_HIGH 10 +#define SPLIT_REND_RO_MD_BAND_THRESH 4 + +#define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4 +#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63 +#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31 +#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 +#define ISAR_SPLIT_REND_D_QUANT_PNTS 15 +#define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f +#define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f + +#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f +#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f +#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS +#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f +#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f + +#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED31_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) + +#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ) + +#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9 +#define ISAR_SPLIT_REND_DOF_BITS 2 +#define ISAR_SPLIT_REND_HQ_MODE_BITS 1 +#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 +#define ISAR_SPLIT_REND_RO_FLAG_BITS 1 + +#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2 + +/*----------------------------------------------------------------------------------* + * Split rendering bitrate constants + *----------------------------------------------------------------------------------*/ + +#define SPLIT_REND_256k 256000 +#define SPLIT_REND_320k 320000 +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 /* == ISAR_MAX_SPLIT_REND_BITRATE */ + + +#endif /*ISAR_CNST_H */ +/* clang-format on */ diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c new file mode 100644 index 0000000000000000000000000000000000000000..03ddb932acfb522222384240b2c181df2b9f26f5 --- /dev/null +++ b/lib_isar/isar_lc3plus_common.c @@ -0,0 +1,94 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "options.h" +#include "isar_lc3plus_common.h" +#include "ivas_error.h" +#include "lc3.h" + +/*-----------------------------------------------------------------------------------------* + * Function ISAR_LC3PLUS_LC3plusErrToIvasErr() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( + const LC3PLUS_Error lc3PlusError ) +{ + switch ( lc3PlusError ) + { + case LC3PLUS_OK: + return IVAS_ERR_OK; + case LC3PLUS_BITRATE_ERROR: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + default: + break; + } + + return IVAS_ERR_INTERNAL; +} + + +/*-----------------------------------------------------------------------------------------* + * Function IVAS_LC3PLUS_LC3plusRtpErrToIvasErr() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( + const LC3PLUS_RTP_ERR lc3PlusRtpError ) +{ + switch ( lc3PlusRtpError ) + { + case LC3PLUS_RTP_ERR_NO_ERROR: + return IVAS_ERR_OK; + case LC3PLUS_RTP_ERR_NULL_PTR: + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + case LC3PLUS_RTP_ERR_INVALID_PARAMETERS: + return IVAS_ERR_WRONG_PARAMS; + case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED: + return IVAS_ERR_NOT_IMPLEMENTED; + case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM: + return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE: + return IVAS_ERR_INVALID_BUFFER_SIZE; + case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_GENERIC_ERROR: + default: + break; + } + + return IVAS_ERR_UNKNOWN; +} diff --git a/lib_rend/ivas_lc3plus_common.h b/lib_isar/isar_lc3plus_common.h similarity index 80% rename from lib_rend/ivas_lc3plus_common.h rename to lib_isar/isar_lc3plus_common.h index 49657d2b2f75c5f8ff8302b0a7961fb297d535c1..1928010bb8306b0f680e79c4805ab3c339b03a88 100644 --- a/lib_rend/ivas_lc3plus_common.h +++ b/lib_isar/isar_lc3plus_common.h @@ -30,28 +30,35 @@ *******************************************************************************************************/ -#ifndef IVAS_LC3PLUS_COM_H -#define IVAS_LC3PLUS_COM_H +#ifndef ISAR_LC3PLUS_COM_H +#define ISAR_LC3PLUS_COM_H #include +#include "options.h" #include "ivas_error.h" #include "lc3.h" +#include "isar_lc3plus_payload.h" /*! common configuration parameters between encoder and decoder */ typedef struct LC3PLUS_CONFIG { /*! frame duration in microseconds [10000, 5000, 2500] */ - uint32_t lc3plus_frame_duration_us; - /*! ivas frame duration in microseconds [20000, 5000] */ - uint32_t ivas_frame_duration_us; + int16_t lc3plus_frame_duration_us; + /*! ISAR frame duration in microseconds [20000, 10000, 5000] */ + int16_t isar_frame_duration_us; /*! sampling rate*/ - uint32_t samplerate; + int32_t samplerate; /*! number of channels */ - uint16_t channels; + int16_t channels; + /*! high resolution mode enabled (1) or disabled (0)*/ + int16_t high_res_mode_enabled; } LC3PLUS_CONFIG; /*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ -ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); -#endif /* IVAS_LC3PLUS_COM_H */ +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ); + +#endif /* ISAR_LC3PLUS_COM_H */ diff --git a/lib_rend/ivas_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c similarity index 57% rename from lib_rend/ivas_lc3plus_dec.c rename to lib_isar/isar_lc3plus_dec.c index a5a663884a8e16e875548c669d741010959031a3..b0dd45d557df9be9ffeb484c769f15d666d1b992 100644 --- a/lib_rend/ivas_lc3plus_dec.c +++ b/lib_isar/isar_lc3plus_dec.c @@ -34,42 +34,42 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" -#include "ivas_lc3plus_dec.h" -#include "ivas_lc3plus_common.h" +#include "isar_lc3plus_dec.h" +#include "isar_lc3plus_common.h" #include "lc3.h" #include "ivas_error_utils.h" #include "wmc_auto.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Open() + * ISAR_LC3PLUS_DEC_Open() * * *------------------------------------------------------------------------*/ -ivas_error IVAS_LC3PLUS_DEC_Open( - const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ - IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ ) { LC3PLUS_Error err; int32_t decoder_size; - int16_t lc3plusFrameIdx; - int16_t numLC3plusFramesPerIvasFrame; int16_t i; - if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + if ( 0 == config.lc3plus_frame_duration_us ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); } - if ( 0 == config.lc3plus_frame_duration_us ) + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } - numLC3plusFramesPerIvasFrame = (int16_t) ( config.ivas_frame_duration_us / config.lc3plus_frame_duration_us ); + if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" ); + } ( *handle )->num_decs = 0; ( *handle )->pcm_conversion_buffer = NULL; @@ -77,15 +77,15 @@ ivas_error IVAS_LC3PLUS_DEC_Open( ( *handle )->selective_decoding_states = NULL; ( *handle )->bitstream_caches = NULL; - if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } - if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL ) + if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } @@ -95,9 +95,9 @@ ivas_error IVAS_LC3PLUS_DEC_Open( ( *handle )->selective_decoding_states[i] = NULL; } - if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL ) + if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } for ( i = 0; i < config.channels; ++i ) @@ -117,75 +117,69 @@ ivas_error IVAS_LC3PLUS_DEC_Open( decoder_size = lc3plus_dec_get_size( config.samplerate, 1 ); if ( 0 == decoder_size ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" ); } if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } - err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled ); + if ( LC3PLUS_OK != err ) { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); } err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); if ( LC3PLUS_OK != err ) { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); } /* allocate and configure per LC3plus decoder skip state */ - if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); - } - - if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL ) + if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; - for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) - { - ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; - } + ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE; /* allocate and configure per LC3plus decoder bitstream cache */ - if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) + if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } - ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; + + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/; + if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0; } ( *handle )->config = config; - if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); } if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL ) { - IVAS_LC3PLUS_DEC_Close( handle ); + ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); } @@ -194,182 +188,13 @@ ivas_error IVAS_LC3PLUS_DEC_Open( /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * ISAR_LC3PLUS_DEC_GetDelay() * * *------------------------------------------------------------------------*/ -ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( - int16_t ***subframeChannelMatrix, - const uint32_t num_decs ) -{ - int16_t i; - - if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); - } - - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - ( *subframeChannelMatrix )[i] = NULL; - } - - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() - * - * - *------------------------------------------------------------------------*/ - -void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( - int16_t **subframeChannelMatrix ) -{ - for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - free( subframeChannelMatrix[i] ); - } - - free( subframeChannelMatrix ); - - return; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ - int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) -{ - int16_t numIvasSubFramesPerLC3frame; - uint32_t decIdx; - int16_t ivasSubframeIdx; - int16_t effectiveIvasSubframeDuration; - int16_t actual_num_spatial_subframes; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); - } - - if ( NULL == subframeChannelMatrix ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); - } - - if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); - } - - effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us ); - numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; - actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; - /* 0.5(0) = 10ms lc3plus, 5ms subframe */ - if ( numIvasSubFramesPerLC3frame != 1 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); - } - - /* map subframeChannelMatrix to lc3plus skip states */ - /* 1st pass: Flag the required frames */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) - { - /* subframe needed by the user, definitely decode */ - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; - } - else - { - - /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ - if ( - ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) - { - /* ... but if the following subframe is required, it needs to be decoded and dropped */ - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; - } - else - { - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; - } - } - } - } - - /* if a decoder was paused before, it needs to either: - * - Decode the cached frame (if available) and the first required frame OR - * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) - { - /* find the first frame required by the user */ - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) - { - /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ - if ( 0 == ivasSubframeIdx ) - { - handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; - break; - } - /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ - else - { - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; - break; - } - } - } - } - } - - /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) - { - handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; - } - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_GetDelay() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_GetDelay( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_GetDelay( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ int32_t *delayInSamples /* o : decoder delay in number of samples per channel */ ) { @@ -377,8 +202,9 @@ ivas_error IVAS_LC3PLUS_DEC_GetDelay( if ( NULL == handle ) { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); } + if ( NULL == delayInSamples ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); @@ -407,13 +233,13 @@ ivas_error IVAS_LC3PLUS_DEC_GetDelay( /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Close() + * ISAR_LC3PLUS_DEC_Close() * * *------------------------------------------------------------------------*/ -void IVAS_LC3PLUS_DEC_Close( - IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */ +void ISAR_LC3PLUS_DEC_Close( + ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */ ) { if ( NULL == handle || NULL == *handle ) @@ -430,7 +256,6 @@ void IVAS_LC3PLUS_DEC_Close( if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) { - free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); free( ( *handle )->selective_decoding_states[iDec] ); } @@ -487,7 +312,7 @@ static ivas_error decode_or_conceal_one_lc3plus_frame( if ( err != LC3PLUS_OK ) { - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); } return IVAS_ERR_OK; @@ -495,13 +320,13 @@ static ivas_error decode_or_conceal_one_lc3plus_frame( /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal() + * isar_LC3PLUS_DEC_Decode_or_Conceal_internal() * * *------------------------------------------------------------------------*/ -static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ +static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ uint8_t *bitstream_in, /* i : pointer to input bitstream */ int32_t bitstream_in_size, /* i : size of bitstream_in */ const int16_t badFrameIndicator, /* i : bad frame indicator. If set to 1, triggers concealment */ @@ -509,13 +334,13 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( ) { uint32_t iDec; - int32_t iLc3plusFrame; - int32_t lc3framesPerIvasFrame; + int32_t config_num_media_times; + int32_t iMediaTime; + int32_t iFtd; + LC3PLUS_RTP_PAYLOAD payload; int32_t ivasSampleIndex; int16_t numSamplesPerLC3plusChannel; - int32_t bitstreamOffsetPerCoder; ivas_error err; - uint8_t *bitstream_in_iter = bitstream_in; if ( NULL == handle ) { @@ -538,19 +363,46 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" ); } - if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); } - lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + if ( !badFrameIndicator ) + { + if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + if ( payload.sampling_rate_hz != handle->config.samplerate ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" ); + } + if ( payload.num_channels != handle->config.channels ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" ); + } + if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" ); + } + if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" ); + } + if ( payload.num_media_times != config_num_media_times ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" ); + } + } - numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame ); - bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times ); for ( iDec = 0; iDec < handle->num_decs; iDec++ ) { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ ) { + iFtd = iDec + iMediaTime * handle->num_decs; if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) { if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) @@ -572,49 +424,47 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( { handle->bitstream_caches[iDec]->bitstream_cache_size = 0; } - switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) + + switch ( handle->selective_decoding_states[iDec]->frame_action ) { - case DEC_ACTION_DECODE_AND_DROP: + case DEC_ACTION_DECODE_AND_USE: { - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); - if ( err != IVAS_ERR_OK ) + if ( badFrameIndicator ) { - return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator ); + } + else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + /* Untested therefore disabled. Would probably only need to call concealment, + * but the LC3plus API requires a non-NULL ptr for this which is not available here */ + } + else + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator ); } - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; - break; - } - case DEC_ACTION_DECODE_AND_USE: - { - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); if ( err != IVAS_ERR_OK ) { return IVAS_ERROR( err, "lc3plus decoding failed\n" ); } - for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) { - ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; } handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; } - case DEC_ACTION_SKIP: - { - /* log that this instance has skipped a frame and must decode twice once reactivated */ - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; - break; - } case DEC_ACTION_CACHE: { - if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); } /* store bit rate of cached frame */ - mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) bitstreamOffsetPerCoder ); - handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder; + mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length ); + handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length; /* log that this instance has skipped a frame and must decode twice once reactivated */ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; break; @@ -623,29 +473,23 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( default: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); } - - bitstream_in_iter += bitstreamOffsetPerCoder; - } - + } /* for each media time */ /* reset skipping state, must be set by the user before each decode call*/ - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE; - } - } + handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE; + } /* for each dec/channel */ return IVAS_ERR_OK; } /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Decode() + * ISAR_LC3PLUS_DEC_Decode() * * *------------------------------------------------------------------------*/ -ivas_error IVAS_LC3PLUS_DEC_Decode( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ +ivas_error ISAR_LC3PLUS_DEC_Decode( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ uint8_t *bitstream_in, /* i : pointer to input bitstream */ const int32_t bitstream_in_size, /* i : size of bitstream_in */ float **pcm_out /* o : decoded samples */ @@ -667,18 +511,18 @@ ivas_error IVAS_LC3PLUS_DEC_Decode( } badFrameIndicator = 0; - return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); + return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); } /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Conceal() + * ISAR_LC3PLUS_DEC_Conceal() * * *------------------------------------------------------------------------*/ -ivas_error IVAS_LC3PLUS_DEC_Conceal( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_Conceal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ float **pcm_out /* o : concealed samples */ ) { @@ -698,6 +542,5 @@ ivas_error IVAS_LC3PLUS_DEC_Conceal( /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */ badFrameIndicator = 1; - return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); + return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); } -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h similarity index 68% rename from lib_rend/ivas_lc3plus_dec.h rename to lib_isar/isar_lc3plus_dec.h index ce4d6281045db590f0cca67ebbcc6211a8b2928c..67f45ca9764dbadb1b62c8596bb9b413504c178d 100644 --- a/lib_rend/ivas_lc3plus_dec.h +++ b/lib_isar/isar_lc3plus_dec.h @@ -30,90 +30,79 @@ *******************************************************************************************************/ -#ifndef IVAS_LC3PLUS_DEC_H -#define IVAS_LC3PLUS_DEC_H +#ifndef ISAR_LC3PLUS_DEC_H +#define ISAR_LC3PLUS_DEC_H #include #include "options.h" #include "lc3.h" #include "ivas_error.h" -#include "ivas_lc3plus_common.h" #include "ivas_cnst.h" +#include "isar_lc3plus_common.h" + typedef enum { - DEC_ACTION_DECODE_AND_DROP = 0, DEC_ACTION_DECODE_AND_USE, - DEC_ACTION_SKIP, DEC_ACTION_CACHE, DEC_ACTION_NUM_ENUMS } SelectiveDecAction; -typedef struct IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE +typedef struct ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE { /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ int16_t has_skipped_a_frame; - /*! if set to 1, decoder will skip decoding for the next frame */ - SelectiveDecAction *frame_actions; + /*! action to execute for the next frame */ + SelectiveDecAction frame_action; /*! if set to 1, decoder will decode the cache before decoding any of current frames */ int16_t shall_decode_cached_frame; -} IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; +} ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; -typedef struct IVAS_LC3PLUS_DEC_BITSTREAM_CACHE +typedef struct ISAR_LC3PLUS_DEC_BITSTREAM_CACHE { uint8_t *bitstream_cache; int32_t bitstream_cache_capacity; int32_t bitstream_cache_size; -} IVAS_LC3PLUS_DEC_BITSTREAM_CACHE; +} ISAR_LC3PLUS_DEC_BITSTREAM_CACHE; /* decoder wrapper */ -typedef struct IVAS_LC3PLUS_DEC_HANDLE +typedef struct ISAR_LC3PLUS_DEC_HANDLE { LC3PLUS_Dec **handles; - IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; - IVAS_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; + ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; + ISAR_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; uint32_t num_decs; int16_t *pcm_conversion_buffer; LC3PLUS_CONFIG config; -} * IVAS_LC3PLUS_DEC_HANDLE; +} * ISAR_LC3PLUS_DEC_HANDLE; -ivas_error IVAS_LC3PLUS_DEC_Open( - const LC3PLUS_CONFIG config, /* i : decoder configuration */ - IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ ); -ivas_error IVAS_LC3PLUS_DEC_GetDelay( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_GetDelay( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ ); -void IVAS_LC3PLUS_DEC_Close( - IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ +void ISAR_LC3PLUS_DEC_Close( + ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ ); -/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ - int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ -); -ivas_error IVAS_LC3PLUS_DEC_Decode( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_Decode( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ uint8_t *bitstream_in, /* i : pointer to input bitstream */ const int32_t bitstream_in_size, /* i : size of bitstream_in */ float **pcm_out /* o : decoded samples */ ); -ivas_error IVAS_LC3PLUS_DEC_Conceal( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_Conceal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ float **pcm_out /* o : concealed samples */ ); -ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( - int16_t ***subframeChannelMatrix, - const uint32_t num_decs ); - -void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); -#endif /* IVAS_LC3PLUS_DEC_H */ +#endif /* ISAR_LC3PLUS_DEC_H */ diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..3a8fd559501f5212746af616489fd2a78ac59ff2 --- /dev/null +++ b/lib_isar/isar_lc3plus_enc.c @@ -0,0 +1,596 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "prot.h" +#include "wmc_auto.h" +#include "options.h" + +static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + +static int32_t limit_per_channel_bitrate( + LC3PLUS_CONFIG config, + const int32_t per_channel_bitrate ) +{ + if ( config.high_res_mode_enabled ) + { + switch ( config.lc3plus_frame_duration_us ) + { + case 10000: + return min( per_channel_bitrate, 500000 ); + case 5000: + return min( per_channel_bitrate, 600000 ); + case 2500: + return min( per_channel_bitrate, 672000 ); + default: + assert( false && "unreachable" ); + } + } + + switch ( config.samplerate ) + { + case 48000: + case 32000: + return min( per_channel_bitrate, 320000 ); + case 24000: + return min( per_channel_bitrate, 314400 ); + case 16000: + return min( per_channel_bitrate, 221600 ); + case 8000: + return min( per_channel_bitrate, 114400 ); + default: + assert( false && "unreachable" ); + } + + assert( false && "unreachable" ); + return -1; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Open() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ + const uint32_t bitsPerSecond, /* i : bit rate */ + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ +) +{ + int32_t num_lc3plus_media_times_per_ivas_frame; + bool is_last_media_time, is_last_channel; + ivas_error ivas_err; + int32_t encoder_size; + LC3PLUS_Error err; + int32_t lfeChans[1]; + int16_t i; + + lfeChans[0] = 0; + + if ( 0U == config.channels ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); + } + + if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" ); + } + if ( config.isar_frame_duration_us != 20000 && config.isar_frame_duration_us != 10000 && config.isar_frame_duration_us != 5000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" ); + } + + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); + if ( 0 == encoder_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); + } + + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + ( *handle )->config = config; + ( *handle )->frame_type_descriptors = NULL; + + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->num_encs = 0; + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + } + ( *handle )->num_encs = config.channels; + + num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us; + ( *handle )->fdl_request = s_fdl_request; + ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame; + ( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) ); + if ( NULL == ( *handle )->frame_type_descriptors ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" ); + } + + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); + } + + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); + } + + err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); + } + } + + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); + } + + /* update FDI fields */ + for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc ) + { + int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs; + + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */ + + if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" ); + } + if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY; + ( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL; + + /* The FTDs in the ToC are included in the following order: + * 1) First the FTD for the first channel of the first FDB (oldest frame) + * 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order + * 3) Then the FTD for the first channel of the second FDB + * 4) Then the FTDs for the remaining channels for the second FDB + * 5) Etc. to the last FDB */ + is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime; + is_last_channel = ( *handle )->num_encs - 1 == iEnc; + if ( is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + } + else if ( !is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + } + else + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + } + } + } + + ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond ); + if ( ivas_err != IVAS_ERR_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return ivas_err; + } + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_SetBitrate() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +) +{ + int32_t numLc3plusMediaTimesPerIvasFrame; + int32_t lc3plus_num_bytes_per_frame; + int32_t availableOctetsPerIsarFrame; + int32_t actualOctetsPerFrame; + LC3PLUS_Error err; + ivas_error ivas_err; + int32_t iFtd; + int32_t fdrLength; + int32_t lc3plusPacketRate; + int32_t numSubframes; + int32_t minPayloadOverhead; + int32_t targetLc3PlusBitratePerChannel; + int32_t targetLc3PlusOctetCount; + int32_t lc3plusFdlLength; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + + availableOctetsPerIsarFrame = bitsPerSecond / ( 1000000 / handle->config.isar_frame_duration_us ) / 8; + lc3plusPacketRate = 1000 * 1000 / handle->config.lc3plus_frame_duration_us; + numLc3plusMediaTimesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSubframes = numLc3plusMediaTimesPerIvasFrame * handle->config.channels; + + /* subtract minimum required payload bytes & calculate a first per-channel target bit rate */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &fdrLength, s_fdl_request ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE ); + targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame; + + if ( targetLc3PlusBitratePerChannel <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" ); + } + + targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel ); + targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate; + /* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &lc3plusFdlLength, targetLc3PlusOctetCount ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + if ( lc3plusFdlLength != LC3PLUS_RTP_FDL_MIN_LENGTH ) + { + /* reduce bitrate to allow for the required fdl field */ + targetLc3PlusBitratePerChannel = ( targetLc3PlusOctetCount - ( lc3plusFdlLength - LC3PLUS_RTP_FDL_MIN_LENGTH ) ) / handle->config.channels * 8 * lc3plusPacketRate; + } + + for ( int32_t iCh = 0; iCh < handle->config.channels; iCh++ ) + { + err = lc3plus_enc_set_bitrate( handle->handles[iCh], targetLc3PlusBitratePerChannel ); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + /* update FTD settings after bitrate change */ + for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc ) + { + iFtd = iEnc + iMediaTime * handle->num_encs; + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + handle->frame_type_descriptors[iFtd].frame_data_length = lc3plus_num_bytes_per_frame; + } + } + + if ( ( ivas_err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ) ) != IVAS_ERR_OK ) + { + return ivas_err; + } + + if ( actualOctetsPerFrame > availableOctetsPerIsarFrame ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Bitrate reduction logic failed\n" ); + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetOutputBitstreamSize() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of each bitstream frame in bytes */ +) +{ + LC3PLUS_RTP_ERR rtp_err; + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t iMediaTime; + int32_t ftd_frame_data_length_size, lc3plus_frame_data_length; + int32_t ftd_index; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == bsSize ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); + } + + if ( 0 == handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" ); + } + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + *bsSize = 0; + int32_t fdl_request_length; + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" ); + } + *bsSize += fdl_request_length; + + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + + for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + ftd_index = iEnc + iMediaTime * handle->num_encs; + if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" ); + } + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" ); + } + *bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + *bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length; + *bsSize += ftd_frame_data_length_size; + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } + + if ( NULL != ( *handle )->frame_type_descriptors ) + { + free( ( *handle )->frame_type_descriptors ); + } + + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) + { + if ( NULL != ( *handle )->handles[iEnc] ) + { + lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); + free( ( *handle )->handles[iEnc] ); + } + } + + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + + free( ( *handle )->handles ); + free( *handle ); + + *handle = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Encode() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **pcm_in, /* i : pointer input samples */ + void *bitstream_out, /* o : pointer to bitstream frame */ + const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ +) +{ + int32_t ftdIndex; + LC3PLUS_RTP_ERR rtpErr; + uint32_t num_media_times; + uint32_t numSamplesPerLC3plusChannel; + int32_t ivasSampleIndex; + int32_t num_bytes = 0; + LC3PLUS_Error err; + + push_wmops( "ISAR_LC3PLUS_ENC_Encode" ); + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); + } + if ( NULL == bitstream_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times; + + size_t actual_size; + rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, s_fdl_request, handle->frame_type_descriptors, handle->num_ftds ); + if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ ) + { + for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; + handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); + } + + ftdIndex = iMediaTime * handle->num_encs + iEnc; + num_bytes = 0; + push_wmops( "lc3plus_enc16" ); + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, NULL ); + pop_wmops(); + + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); + } + + if ( 0 == num_bytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); + } + + if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" ); + } + } + } + + pop_wmops(); + + return IVAS_ERR_OK; +} diff --git a/lib_rend/ivas_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h similarity index 63% rename from lib_rend/ivas_lc3plus_enc.h rename to lib_isar/isar_lc3plus_enc.h index a4ea7c808faf20e857e8666f5ed07c9e81036999..4a5251d646abb7b33d3cc1f1ba18805dc78b4156 100644 --- a/lib_rend/ivas_lc3plus_enc.h +++ b/lib_isar/isar_lc3plus_enc.h @@ -30,47 +30,57 @@ *******************************************************************************************************/ -#ifndef IVAS_LC3PLUS_ENC_H -#define IVAS_LC3PLUS_ENC_H +#ifndef ISAR_LC3PLUS_ENC_H +#define ISAR_LC3PLUS_ENC_H #include -#include "lc3.h" #include "ivas_error.h" -#include "ivas_lc3plus_common.h" +#include "lc3.h" +#include "isar_lc3plus_common.h" +#include "isar_lc3plus_payload.h" /* encoder wrapper */ -typedef struct IVAS_LC3PLUS_ENC_HANDLE +typedef struct ISAR_LC3PLUS_ENC_HANDLE { LC3PLUS_CONFIG config; LC3PLUS_Enc **handles; uint32_t num_encs; int16_t *pcm_conversion_buffer; -} * IVAS_LC3PLUS_ENC_HANDLE; + LC3PLUS_RTP_FTD *frame_type_descriptors; + int32_t num_ftds; + LC3PLUS_RTP_FDL fdl_request; +} * ISAR_LC3PLUS_ENC_HANDLE; + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : encoder configuration */ + const uint32_t initialBitsPerSecond, /* i : initial target bit rate */ + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ +); -ivas_error IVAS_LC3PLUS_ENC_Open( - const LC3PLUS_CONFIG config, /* i : encoder configuration */ - const uint32_t bitsPerSecond, /* i : bit rate */ - IVAS_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ ); -ivas_error IVAS_LC3PLUS_ENC_GetDelay( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ ); -ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *bsSize /* o : size of each bitstream frame in bytes */ +ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of next bitstream frame in bytes */ ); -void IVAS_LC3PLUS_ENC_Close( - IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ ); -ivas_error IVAS_LC3PLUS_ENC_Encode( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - float **pcm_in, /* i : pointer input samples */ - void *bitstream_out /* o : pointer to bitstream frame */ +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **pcm_in, /* i : pointer input samples */ + void *bitstream_out, /* o : pointer to bitstream frame */ + const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ ); -#endif /* IVAS_LC3PLUS_ENC_H */ +#endif /* ISAR_LC3PLUS_ENC_H */ diff --git a/lib_isar/isar_lc3plus_payload.c b/lib_isar/isar_lc3plus_payload.c new file mode 100644 index 0000000000000000000000000000000000000000..cec09837a23946f371004d7201ee08090906d21b --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.c @@ -0,0 +1,908 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "options.h" + + +/*------------------------------------------------------------------------- + * Local functions + *------------------------------------------------------------------------*/ + +static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( + int32_t *frame_duration_us, + const LC3PLUS_RTP_FTD_FDI fdi ) +{ + if ( NULL == frame_duration_us ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( fdi ) + { + case LC3PLUS_RTP_FTD_FDI_2500_US: + *frame_duration_us = 2500; + break; + case LC3PLUS_RTP_FTD_FDI_5000_US: + *frame_duration_us = 5000; + break; + case LC3PLUS_RTP_FTD_FDI_10000_US: + *frame_duration_us = 10000; + break; + case LC3PLUS_RTP_FTD_FDI_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( + int32_t *sample_rate_hz, + const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == sample_rate_hz ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *sample_rate_hz = 8000; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *sample_rate_hz = 16000; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *sample_rate_hz = 24000; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *sample_rate_hz = 32000; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *sample_rate_hz = 44100; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *sample_rate_hz = 96000; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( + int16_t *high_resolution_flag, + const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == high_resolution_flag ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *high_resolution_flag = 1; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *high_resolution_flag = 1; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_frame_data_length_get_size() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( + int32_t *length, + const LC3PLUS_RTP_FDL frameDataLengthValue ) +{ + if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX ) + { + *length = 2; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + *length = 3; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +static LC3PLUS_RTP_ERR s_frame_data_length_pack( + const LC3PLUS_RTP_FDL frameDataLengthValue, + uint8_t *dst ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + + if ( NULL == dst ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + if ( 1 == frame_data_length_size ) + { + *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 2 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 3 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE ); + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +static int32_t s_get_size_from_fdl( + const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + return fdl; + } + + return 0; +} + + +static bool s_fdl_is_magic_value( + const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return true; + } + + return false; +} + + +static bool s_fdl_value_is_valid_request( + const LC3PLUS_RTP_FDL fdl_request ) +{ + /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */ + if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) ) + { + return true; + } + + return false; +} + + +static LC3PLUS_RTP_ERR s_frame_data_length_parse( + LC3PLUS_RTP_FDL *frame_data_length_value, + const uint8_t *src, + const size_t remaining_capacity ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + + if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) ) + { + *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src ) + { + *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 0 ) + { + *frame_data_length_value = *src << 0; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + + /* sanity check */ + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +static LC3PLUS_RTP_ERR s_parse_ftd( + const uint8_t *p_read, + LC3PLUS_RTP_FTD *receiver_ftd, + int32_t *num_bytes_read, + const size_t remaining_capacity ) +{ + int32_t frame_data_block_size; + LC3PLUS_RTP_FDL fdl; + LC3PLUS_RTP_ERR err; + + if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *num_bytes_read = 0; + receiver_ftd->fc = 0; + receiver_ftd->fdi = 0; + receiver_ftd->bwr = 0; + receiver_ftd->h = 0; + receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK; + receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK ); + receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK ); + receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK ); + p_read++; + *num_bytes_read = 1; + + err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + frame_data_block_size = s_get_size_from_fdl( fdl ); + + receiver_ftd->frame_data_length = frame_data_block_size; + int32_t length_field_size; + err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + *num_bytes_read += length_field_size; + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_payload_serialize() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ) +{ + LC3PLUS_RTP_ERR err; + uint8_t *p_write = serialized_buffer; + uint32_t i; + int32_t bytes_written = 0; + int32_t lc3plus_frame_size_sum; + uint8_t *p_frame_data; + int32_t fdl_request_length; + + if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *packed_buffer_actual_size = 0; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( fdl_request, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + bytes_written += fdl_request_length; + p_write += bytes_written; + + for ( i = 0; i < sender_ftds_num; ++i ) + { + /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + *p_write = 0x00; + *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc; + *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi; + *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr; + *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h; + p_write++; + bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + + int32_t fdl_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + p_write += fdl_length; + bytes_written += fdl_length; + } + + lc3plus_frame_size_sum = 0; + p_frame_data = serialized_buffer + bytes_written; + for ( i = 0; i < sender_ftds_num; ++i ) + { + sender_ftds[i].frame_data = p_frame_data; + p_frame_data += sender_ftds[i].frame_data_length; + lc3plus_frame_size_sum += sender_ftds[i].frame_data_length; + } + *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum; + assert( *packed_buffer_actual_size <= serialized_buffer_capacity ); + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +static LC3PLUS_RTP_ERR s_ftds_parse( + LC3PLUS_RTP_FTD *receiver_ftds, + const int32_t receiver_ftds_num_max, + int16_t *receiver_ftds_num, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t diff; + uint8_t *p_read; + uint32_t ftds_offset_sum = 0; + int16_t i; + LC3PLUS_RTP_ERR error; + int32_t frame_offset_counter; + int32_t size; + + p_read = serialized_buffer; + if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_EMPTY_TOC; + } + if ( receiver_ftds_num_max <= 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + { + int32_t num_bytes_read_sum = 0; + const int32_t min_num_bytes_per_ftd = 2; + int16_t receiver_ftds_index = 0; + bool another_ftd = true; + int32_t num_bytes_read_per_ftd; + + while ( another_ftd ) + { + if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + num_bytes_read_per_ftd = 0; + error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != error ) + { + return error; + } + p_read += num_bytes_read_per_ftd; + num_bytes_read_sum += num_bytes_read_per_ftd; + + if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL ) + { + another_ftd = false; + } + + if ( another_ftd ) + { + if ( receiver_ftds_index >= receiver_ftds_num_max ) + { + return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED; + } + ( receiver_ftds_index )++; + } + } + *receiver_ftds_num = receiver_ftds_index + 1; + } + + /* set frame-data pointers into serialized_buffer */ + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return error; + } + ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size; + } + + frame_offset_counter = 0; + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) ) + { + receiver_ftds[i].frame_data = NULL; + } + else + { + receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter; + frame_offset_counter += receiver_ftds[i].frame_data_length; + } + } + + if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size ) + { + /* parsed content & size n bytes of input buffer do not line up */ + /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */ + diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter ); + if ( diff < 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + /* verify that all bytes are zero */ + p_read += frame_offset_counter; + for ( i = 0; i < diff; ++i ) + { + if ( *p_read != 0 ) + { + /* non-zero byte in padding region */ + return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES; + } + p_read++; + } + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_payload_deserialize() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t new_frame_duration_us; + int32_t new_sampling_rate_hz; + int16_t new_high_resolution_flag; + int16_t i = 0; + int16_t channel_id = 0; + int16_t media_time_id = 0; + const int16_t invalid_value = -1; + int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS]; + int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES]; + LC3PLUS_RTP_ERR err; + + if ( NULL == payload || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id ) + { + channels_per_media_time[media_time_id] = invalid_value; + } + media_time_id = 0; + for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id ) + { + media_times_per_channel[channel_id] = invalid_value; + } + channel_id = 0; + + err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + int32_t fdl_request_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( payload->fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + + err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( 0 == payload->num_ftds ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */ + + /* initialize on the first FTD, use this as reference */ + err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + payload->num_channels = 0; + payload->num_media_times = 0; + for ( i = 0; i < payload->num_ftds; ++i ) + { + if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY ) + { + /* not implemented */ + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + + err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->frame_duration_us != new_frame_duration_us ) + { + /* mixed frame durations not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->sampling_rate_hz != new_sampling_rate_hz ) + { + /* mixed sampling frequencies not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + + err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->high_resolution_enabled != new_high_resolution_flag ) + { + /* mixed high resolution mode not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + switch ( payload->ftds[i].fc ) + { + case LC3PLUS_RTP_FTD_FC_LAST_OVERALL: + channels_per_media_time[media_time_id]++; + media_times_per_channel[channel_id]++; + channel_id = 0; + media_time_id = 0; + break; + case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id++; + break; + case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id = 0; + media_time_id++; + break; + case LC3PLUS_RTP_FTD_FC_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + } + + { + int32_t valid_num_media_times_per_channel; + int32_t iCh; + /* check whether all channels exist for each media time */ + if ( media_times_per_channel[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_media_times_per_channel = media_times_per_channel[0]; + for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh ) + { + if ( media_times_per_channel[iCh] == invalid_value ) + { + break; + } + if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + { + /* whether all media times exist for each channel */ + int32_t iMediaTime; + int32_t valid_num_channels_per_media_time; + if ( channels_per_media_time[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_channels_per_media_time = channels_per_media_time[0]; + for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime ) + { + if ( channels_per_media_time[iMediaTime] == invalid_value ) + { + break; + } + if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + + /* convert zero-index to count */ + payload->num_channels = channels_per_media_time[0] + 1; + payload->num_media_times = media_times_per_channel[0] + 1; + + /* verify that all media times have the same number of channels, partial packets are not supported */ + if ( payload->num_ftds != payload->num_channels * payload->num_media_times ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + + return LC3PLUS_RTP_ERR_NO_ERROR; +} + + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_ftd_bwr_from_samplerate() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( + LC3PLUS_RTP_FTD_BWR *bwr, + const int32_t sampling_rate, + const int32_t high_res_enabled ) +{ + if ( NULL == bwr ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( sampling_rate ) + { + case 8000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_NB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 16000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_WB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 24000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SSWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 32000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 44100: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_FBCD; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 48000: + if ( 0 == high_res_enabled ) + { + *bwr = LC3PLUS_RTP_FTD_BWR_FB; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + else + { + *bwr = LC3PLUS_RTP_FTD_BWR_FBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + case 96000: + if ( 0 == high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_UBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_ftd_fdi_from_frame_duration_us() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( + LC3PLUS_RTP_FTD_FDI *fdi, + const int32_t frame_duration_us ) +{ + if ( NULL == fdi ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( frame_duration_us ) + { + case 2500: + *fdi = LC3PLUS_RTP_FTD_FDI_2500_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 5000: + *fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 10000: + *fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h new file mode 100644 index 0000000000000000000000000000000000000000..ee6e7efe6e91278a59070373032172eb46a0c90e --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.h @@ -0,0 +1,212 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_LC3PLUS_PAYLOAD_H +#define ISAR_LC3PLUS_PAYLOAD_H + +#include +#include +#include "lc3.h" +#include "options.h" + + +/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format + * for LC3plus as specified in ETSI TS 103 634. */ + +typedef enum LC3PLUS_RTP_ERR +{ + LC3PLUS_RTP_ERR_NO_ERROR, + LC3PLUS_RTP_ERR_NULL_PTR, + LC3PLUS_RTP_ERR_INVALID_PARAMETERS, + LC3PLUS_RTP_ERR_EMPTY_TOC, + LC3PLUS_RTP_ERR_NOT_IMPLEMENTED, + LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE, + LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED, + LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST, + LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES, + LC3PLUS_RTP_ERR_GENERIC_ERROR +} LC3PLUS_RTP_ERR; + +/* + * The content of the FTD is shown in Figure B.6. + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* FC (2 bits): + * Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC + * indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments + * of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent + * FTD (if available). */ +typedef enum LC3PLUS_RTP_FTD_FC +{ + LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */ + LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */ + LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */ + LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */ +} LC3PLUS_RTP_FTD_FC; +#define LC3PLUS_RTP_FTD_FC_MASK 0x03 + +/* FDI (2 bits): + * Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given + * payload type during the session. The FDI also dictates the TSI, needed for deriving the media + * time in case of more than one frame in the payload. */ +typedef enum LC3PLUS_RTP_FTD_FDI +{ + LC3PLUS_RTP_FTD_FDI_2500_US = 0x00, + LC3PLUS_RTP_FTD_FDI_5000_US = 0x04, + LC3PLUS_RTP_FTD_FDI_10000_US = 0x08, + LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C, +} LC3PLUS_RTP_FTD_FDI; +#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ); + +/* BWR (3 bits): + * Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and + * resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is + * defined in Table B.4. The BWR index shall be static for a given payload type during the session. */ +typedef enum LC3PLUS_RTP_FTD_BWR +{ + LC3PLUS_RTP_FTD_BWR_NB = 0x00, + LC3PLUS_RTP_FTD_BWR_WB = 0x10, + LC3PLUS_RTP_FTD_BWR_SSWB = 0x20, + LC3PLUS_RTP_FTD_BWR_SWB = 0x30, + LC3PLUS_RTP_FTD_BWR_FBCD = 0x40, + LC3PLUS_RTP_FTD_BWR_FB = 0x50, + LC3PLUS_RTP_FTD_BWR_FBHR = 0x60, + LC3PLUS_RTP_FTD_BWR_UBHR = 0x70, +} LC3PLUS_RTP_FTD_BWR; +#define LC3PLUS_RTP_FTD_BWR_MASK 0x70 +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ); + +/* H (1 bit): + * Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame + * (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */ +typedef enum LC3PLUS_RTP_FTD_H +{ + LC3PLUS_RTP_FTD_H_PRIMARY = 0x00, + LC3PLUS_RTP_FTD_H_SECONDARY = 0x80, +} LC3PLUS_RTP_FTD_H; +#define LC3PLUS_RTP_FTD_H_MASK 0x80 + +typedef enum LC3PLUS_RTP_FDL +{ + LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0, + LC3PLUS_RTP_FDL_SPEECH_BAD = 1, + LC3PLUS_RTP_FDL_SPEECH_SID = 2, + LC3PLUS_RTP_FDL_RESERVED_MIN = 3, + LC3PLUS_RTP_FDL_RESERVED_MAX = 19, + LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20, + LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254, + LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255, + LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509, + LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510, + LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765 +} LC3PLUS_RTP_FDL; +/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */ +#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF + +typedef struct LC3PLUS_RTP_FTD +{ + LC3PLUS_RTP_FTD_FC fc; + LC3PLUS_RTP_FTD_FDI fdi; + LC3PLUS_RTP_FTD_BWR bwr; + LC3PLUS_RTP_FTD_H h; + uint8_t *frame_data; + LC3PLUS_RTP_FDL frame_data_length; +} LC3PLUS_RTP_FTD; +#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1 +#define LC3PLUS_RTP_FDL_MIN_LENGTH 1 +#define LC3PLUS_RTP_FTD_MIN_SIZE ( LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + LC3PLUS_RTP_FDL_MIN_LENGTH ) + +/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer + * @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to + * @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes + * @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity) + * @param[in] fdl_request frame data length request + * @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in + * the packed_buffer (so it can subsequently be used as input for the LC3plus encode call) + * @param[in] sender_ftds_num number of sender_ftds + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ); + +/*! Get size of the frame data length field for a certain frame data length value in bytes. + * @param[out] length size of the frame data length field in bytes [1,2,3] + * @param[in] frameDataLengthValue frame data length value + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ); + +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16 +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */ +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES + +typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG +{ + /* frame duration in us shared among all FTDs */ + int32_t frame_duration_us; + /* high resolution flag shared among all FTDs */ + int16_t high_resolution_enabled; + /* sampling frequency shared among all FTDs */ + int32_t sampling_rate_hz; + /* number of individual channels in the payload */ + int16_t num_channels; + /* number of individual media times in the payload */ + int16_t num_media_times; + /* frame data length request */ + LC3PLUS_RTP_FDL fdl_request; + /* FTD data with pointer to raw frame data */ + LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS]; + /* actual number of ftds */ + int16_t num_ftds; +} LC3PLUS_RTP_PAYLOAD; + +/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct + * @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer. + * @param serialized_buffer pointer to the start of the serialized input buffer + * @param serialized_buffer_size size of the serialized input buffer in bytes + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ); + +#endif /* ISAR_LC3PLUS_PAYLOAD_H */ diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c similarity index 74% rename from lib_rend/ivas_lcld_decoder.c rename to lib_isar/isar_lcld_decoder.c index b98b4f4e00ef2cae0f2328217b857d5e0fc11e30..3482c67e95a7b30ee38288dfb40dee2242feee9f 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_isar/isar_lcld_decoder.c @@ -32,12 +32,11 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" #include "prot.h" #include -#include "ivas_prot_rend.h" +#include "isar_prot.h" #include "wmc_auto.h" @@ -60,6 +59,7 @@ typedef struct TableNode int32_t *piDifference; int32_t *piLength; } TableNode; + typedef struct TableList { TableNode *poOrderedTop; @@ -93,6 +93,7 @@ struct LCLD_DECODER int32_t ***pppiAlloc; int32_t iAllocOffset; + int32_t iRealOnlyOut; int32_t ***pppiLCLDSignReal; int32_t ***pppiLCLDSignImag; @@ -101,26 +102,41 @@ struct LCLD_DECODER PredictionDecoder *psPredictionDecoder; - NoiseGen *psNoiseGen; }; -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ); -static TableNode *CreateTableList( int32_t iReadLength ); + +/*------------------------------------------------------------------------------------------* + * Local functions declarations + *------------------------------------------------------------------------------------------*/ + +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, const uint16_t ( *ppuiEncTable )[2], const int32_t iSize, const int32_t iReadLength, uint32_t *iTables ); + +static TableNode *CreateTableList( const int32_t iReadLength ); + static void DeleteTableList( TableList *ptable_list, int32_t iTables ); -static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ); -static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ); -static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ); -static TableNode *CreateTableList( int32_t iReadLength ) +static TableNode *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated ); + +static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables ); + +static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated ); + + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static TableNode *CreateTableList( + const int32_t iReadLength ) { int32_t n; int32_t iMaxTables; TableNode *ptable_top; + iMaxTables = 1 << iReadLength; ptable_top = (TableNode *) malloc( sizeof( TableNode ) ); - ptable_top->ppoNextTable = - (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); + ptable_top->ppoNextTable = (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); ptable_top->piCodeIndex = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); ptable_top->piDifference = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); ptable_top->piLength = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); @@ -134,15 +150,18 @@ static TableNode *CreateTableList( int32_t iReadLength ) return ptable_top; } -static void DeleteTableList( TableList *ptable_list, int32_t iTables ) + + +static void DeleteTableList( + TableList *ptable_list, + int32_t iTables ) { TableNode *node; node = ptable_list->poOrderedTop; - while ( ( iTables ) ) + while ( iTables ) { - TableNode *node1 = node; node = node1->poOrderedNext; if ( node1->piCodeIndex != NULL ) @@ -167,12 +186,22 @@ static void DeleteTableList( TableList *ptable_list, int32_t iTables ) } iTables--; } + if ( ptable_list != NULL ) { free( ptable_list ); } + + return; } -static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ) + + +static TableNode *GetNextTable( + const int32_t iIndex, + TableList *table_list, + TableNode *poParent, + const int32_t iReadLength, + uint32_t *iTablesCreated ) { TableNode *poNextNode; @@ -193,16 +222,21 @@ static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode return poNextNode; } -static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ) -{ + +static void CompleteTables( + LCLDDecoder *psLCLDDecoder, + const int32_t n, + TableList *ptable_list, + const int32_t iReadLength, + const int32_t iTablesCreated ) +{ int32_t iMaxTables; int32_t j; TableNode *poNode; iMaxTables = 1 << iReadLength; - psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = - malloc( iTablesCreated * iMaxTables * sizeof( uint32_t * ) ); + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) ); poNode = ptable_list->poOrderedTop; for ( j = 0; j < iTablesCreated; j++ ) @@ -221,8 +255,18 @@ static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *pt } poNode = poNode->poOrderedNext; } + + return; } -static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ) + + +static void AddcodeTableList( + TableList *ptable_list, + const int32_t iLength, + const int32_t iCode, + const int32_t iCodeIndex, + const int32_t iReadLength, + uint32_t *iTables ) { int32_t iDifference; int32_t iMask; @@ -230,8 +274,8 @@ static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t i int32_t iIndex; int32_t iCodeLow; int32_t iCodeHigh; - TableNode *poNode; + poNode = ptable_list->poOrderedTop; iMask = ( 1 << iReadLength ) - 1; iCurrentLength = iLength; @@ -255,19 +299,29 @@ static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t i poNode->piDifference[iIndex] = iDifference; poNode->piLength[iIndex] = iLength; } + + return; } -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ) + +static void CreateDecodeTable( + LCLDDecoder *psLCLDDecoder, + const int32_t num, + const uint16_t ( *ppuiEncTable )[2], + const int32_t iSize, + const int32_t iReadLength, + uint32_t *iTables ) { int32_t n; uint32_t **ppsort_enc_table; TableList *ptable_list; + ptable_list = (TableList *) malloc( sizeof( TableList ) ); ppsort_enc_table = (uint32_t **) malloc( iSize * sizeof( int32_t * ) ); + for ( n = 0; n < iSize; n++ ) { - ppsort_enc_table[n] = (uint32_t *) malloc( 3 * sizeof( int32_t ) ); ppsort_enc_table[n][0] = (uint32_t) ppuiEncTable[n][0]; ppsort_enc_table[n][1] = (uint32_t) ppuiEncTable[n][1]; @@ -321,8 +375,7 @@ static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const ui iLength = ppsort_enc_table[n][0]; iCode = ppsort_enc_table[n][1]; iCodeIndex = ppsort_enc_table[n][2]; - AddcodeTableList( ptable_list, iLength, iCode, iCodeIndex, iReadLength, - iTables ); + AddcodeTableList( ptable_list, iLength, iCode, iCodeIndex, iReadLength, iTables ); } CompleteTables( psLCLDDecoder, num, ptable_list, iReadLength, *iTables ); @@ -331,7 +384,10 @@ static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const ui { free( ppsort_enc_table[n] ); } + free( ppsort_enc_table ); + + return; } @@ -345,7 +401,8 @@ ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, const int32_t iChannels, - const int32_t iNumBlocks ) + const int32_t iNumBlocks, + const int32_t iRealOnlyOut ) { int32_t n; int32_t read_length; @@ -360,9 +417,16 @@ ivas_error CreateLCLDDecoder( } psLCLDDecoder->iSampleRate = iSampleRate; psLCLDDecoder->iChannels = iChannels; - psLCLDDecoder->iNumBlocks = iNumBlocks; psLCLDDecoder->iAllocOffset = 0; - + psLCLDDecoder->iRealOnlyOut = iRealOnlyOut; + if ( iRealOnlyOut == 1 ) + { + psLCLDDecoder->iNumBlocks = iNumBlocks / 2; + } + else + { + psLCLDDecoder->iNumBlocks = iNumBlocks; + } psLCLDDecoder->iNumBands = 0; /* read from bitstream*/ psLCLDDecoder->piBandwidths = c_aiBandwidths48; @@ -531,7 +595,8 @@ ivas_error CreateLCLDDecoder( * *------------------------------------------------------------------------------------------*/ -void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) +void DeleteLCLDDecoder( + LCLDDecoder *psLCLDDecoder ) { int32_t k, n; @@ -686,8 +751,11 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder ); } + + return; } + /*------------------------------------------------------------------------------------------* * Local function declarations * @@ -702,24 +770,175 @@ static void InvQuantizeSpectrum( const int32_t iNumGroups, const int32_t *piGrou static void InvMSCoding( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, float ***pppfReal, float ***pppfImag ); -static int32_t ReadHeaderInformation( int32_t *piNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t ReadHeaderInformation( int32_t *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ReadAllocInformation( int32_t *piAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t ReadAllocInformation( int32_t *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t -ReadLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, IVAS_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); +static int32_t ReadLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiDecodingUnresolved, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiSMR, const int32_t iAllocOffset, int32_t ***pppiAlloc ); +/*------------------------------------------------------------------------------------------* + * function LSetDecodingUnresolved() + * + * + *------------------------------------------------------------------------------------------*/ + +void SetDecodingUnresolved( + LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailed[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = 1; + } + } + + return; +} + + +/*------------------------------------------------------------------------------------------* + * function AnyDecodingFailedPrev() + * + * + *------------------------------------------------------------------------------------------*/ + +int16_t AnyDecodingFailedPrev( + LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailedPrev[ch][n] == 1 ) + { + return 1; + } + } + } + + return 0; +} + +/*------------------------------------------------------------------------------------------* + * function AnyDecodingFailed() + * + * + *------------------------------------------------------------------------------------------*/ + +int16_t AnyDecodingFailed( + LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailed[ch][n] == 1 ) + { + return 1; + } + } + } + + return 0; +} + + +/*------------------------------------------------------------------------------------------* + * function GetDecodingFailedStatus() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t **GetDecodingFailedStatus( + LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed; +} + + +/*------------------------------------------------------------------------------------------* + * function GetNumSubSets() + * + * + *------------------------------------------------------------------------------------------*/ + +int16_t GetNumSubSets( + LCLDDecoder *psLCLDDecoder ) +{ + return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets; +} + + +/*------------------------------------------------------------------------------------------* + * function GetDecodingFailedPrevStatus() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t **GetDecodingFailedPrevStatus( + LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev; +} + + +/*------------------------------------------------------------------------------------------* + * function UnpackReal() + * + * + *------------------------------------------------------------------------------------------*/ + +static void UnpackReal( + const int32_t iChannels, + const int32_t iNumBlocks, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t ch, b, n; + + for ( ch = 0; ch < iChannels; ch++ ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + int32_t iRealBlock = iNumBlocks - 1; + for ( n = iNumBlocks / 2 - 1; n >= 0; n-- ) + { + pppfReal[ch][iRealBlock][b] = pppfImag[ch][n][b] * 2.0f; + pppfReal[ch][iRealBlock - 1][b] = pppfReal[ch][n][b] * 2.0f; + pppfImag[ch][iRealBlock][b] = 0.0f; + pppfImag[ch][iRealBlock - 1][b] = 0.0f; + iRealBlock -= 2; + } + } + } + + return; +} + + /*------------------------------------------------------------------------------------------* * Function DecodeLCLDFrame() * @@ -728,7 +947,7 @@ static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGrou int32_t DecodeLCLDFrame( LCLDDecoder *psLCLDDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ float ***pppfLCLDReal, float ***pppfLCLDImag ) { @@ -742,12 +961,13 @@ int32_t DecodeLCLDFrame( } ReadPredictors( psLCLDDecoder->psPredictionDecoder, pBits ); + UpdateDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); + UpdateDecodingFailedStatus( psLCLDDecoder->psPredictionDecoder ); ReadGroupInformation( psLCLDDecoder->iChannels, psLCLDDecoder->iNumBlocks, &psLCLDDecoder->iCommonGrouping, psLCLDDecoder->piNumGroups, psLCLDDecoder->ppiGroupLengths, pBits ); ReadRMSEnvelope( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); - ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iCommonGrouping == 1 ) @@ -776,20 +996,23 @@ int32_t DecodeLCLDFrame( ComputeAllocation( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiSMR, psLCLDDecoder->iAllocOffset, psLCLDDecoder->pppiAlloc ); - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - ReadLCLDData( - psLCLDDecoder->piNumGroups[n], - (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], - psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, - (const int32_t *) - psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n], - psLCLDDecoder->pppiAlloc[n], - psLCLDDecoder->pppiLCLDSignReal[n], psLCLDDecoder->pppiLCLDSignImag[n], - psLCLDDecoder->pppiQLCLDReal[n], psLCLDDecoder->pppiQLCLDImag[n], - pBits, - psLCLDDecoder->c_apauiHuffDecTable_RAM ); - } + ReadLCLDData( + psLCLDDecoder->piNumGroups, + psLCLDDecoder->ppiGroupLengths, + psLCLDDecoder->iNumBands, + psLCLDDecoder->iChannels, + psLCLDDecoder->psPredictionDecoder->ppiDecodingUnresolved, + psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable, + psLCLDDecoder->psPredictionDecoder->iNumSubSets, + psLCLDDecoder->psPredictionDecoder->iSubSetId, + psLCLDDecoder->pppiAlloc, + psLCLDDecoder->pppiLCLDSignReal, + psLCLDDecoder->pppiLCLDSignImag, + psLCLDDecoder->pppiQLCLDReal, + psLCLDDecoder->pppiQLCLDImag, + psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed, + pBits, + psLCLDDecoder->c_apauiHuffDecTable_RAM ); for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) { @@ -843,7 +1066,15 @@ int32_t DecodeLCLDFrame( pppfLCLDReal, pppfLCLDImag ); } - return 0; + if ( psLCLDDecoder->iRealOnlyOut == 1 ) + { + UnpackReal( psLCLDDecoder->iChannels, + psLCLDDecoder->iNumBlocks * 2, + pppfLCLDReal, + pppfLCLDImag ); + } + + return AnyDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); } @@ -894,6 +1125,7 @@ static void ApplyRMSEnvelope( return; } + static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, @@ -1026,6 +1258,7 @@ static void InvMSCoding( int32_t n; int32_t phaseIdx; float fPred; + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; fPred = dequantPred( piMSPredCoefs[bMSPred] ); for ( n = 0; n < piBandwidths[b]; n++ ) @@ -1051,7 +1284,7 @@ static void InvMSCoding( if ( iMSMode == 3 ) { - cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); + cplxmult_lcld( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); } pppfReal[0][k][iFBOffset] = fLeftReal; @@ -1074,15 +1307,14 @@ static void InvMSCoding( } -/* Currently only the number of bands in frame */ static int32_t ReadHeaderInformation( int32_t *piNumBands, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsRead; iBitsRead = 0; - *piNumBands = ivas_split_rend_bitstream_read_int32( pBits, 5 ); + *piNumBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 5 ); iBitsRead += 5; return iBitsRead; @@ -1095,12 +1327,12 @@ static int32_t ReadMSInformation( int32_t *piMSFlags, int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsRead; iBitsRead = 0; - *piMSMode = ivas_split_rend_bitstream_read_int32( pBits, 2 ); + *piMSMode = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 2 ); iBitsRead += 2; if ( *piMSMode == 0 ) @@ -1124,7 +1356,7 @@ static int32_t ReadMSInformation( int32_t n; for ( n = 0; n < iNumBands; n++ ) { - piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; } } @@ -1134,7 +1366,7 @@ static int32_t ReadMSInformation( int32_t iMSPredAll; int32_t iNumMSPredBands = 0; int32_t anyNonZero; - iMSPredAll = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iMSPredAll = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( iMSPredAll ) { @@ -1148,7 +1380,7 @@ static int32_t ReadMSInformation( { for ( n = 0; n < iNumBands; n++ ) { - piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( piMSFlags[n] ) { @@ -1156,10 +1388,12 @@ static int32_t ReadMSInformation( } } } - anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + if ( anyNonZero ) { - piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS ); + piLRPhaseDiffs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PHASE_BAND0_BITS ); piLRPhaseDiffs[0] += PHASE_MIN_VAL; iBitsRead += PHASE_BAND0_BITS; for ( n = 1; n < iNumMSPredBands; n++ ) @@ -1177,10 +1411,12 @@ static int32_t ReadMSInformation( piLRPhaseDiffs[n] = 0; } } - anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + if ( anyNonZero ) { - piMSPredCoefs[0] = ivas_split_rend_bitstream_read_int32( pBits, PRED_BAND0_BITS ); + piMSPredCoefs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_BAND0_BITS ); piMSPredCoefs[0] += PRED_MIN_VAL; iBitsRead += PRED_BAND0_BITS; for ( n = 1; n < iNumMSPredBands; n++ ) @@ -1215,20 +1451,21 @@ static int32_t ReadMSInformation( return iBitsRead; } + static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t c, k, iBitsRead; iBitsRead = 0; if ( iChannels == 2 ) { - *piCommonGrouping = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + *piCommonGrouping = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( *piCommonGrouping == 1 ) @@ -1239,7 +1476,7 @@ static int32_t ReadGroupInformation( { int32_t iGroupStart; - iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( iGroupStart == 1 ) @@ -1270,7 +1507,7 @@ static int32_t ReadGroupInformation( { int32_t iGroupStart; - iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( iGroupStart == 1 ) @@ -1297,7 +1534,7 @@ static int32_t ReadGroupInformation( { int32_t iGroupStart; - iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); iBitsRead += 1; if ( iGroupStart == 1 ) @@ -1319,7 +1556,7 @@ static int32_t ReadGroupInformation( static int32_t BSForceBack( - IVAS_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, int32_t iValue, int32_t iBitCount ) { @@ -1332,7 +1569,7 @@ static int32_t BSForceBack( static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsRead; int32_t iSymbol; @@ -1345,7 +1582,7 @@ static int32_t ReadHuff( iBitsRead = 0; while ( iSymbol == 0xFFFF ) { - iIndex = ivas_split_rend_bitstream_read_int32( pBits, HUFF_READ_SIZE ); + iIndex = ISAR_SPLIT_REND_BITStream_read_int32( pBits, HUFF_READ_SIZE ); iBitsRead += HUFF_READ_SIZE; iIndex = pauiHuffDecTable[iVal][iIndex]; @@ -1371,7 +1608,7 @@ static int32_t ReadRMSEnvelope( const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t b, k, n; int32_t iBitsRead, iLastRMSVal; @@ -1381,7 +1618,7 @@ static int32_t ReadRMSEnvelope( { for ( k = 0; k < piNumGroups[n]; k++ ) { - iLastRMSVal = ivas_split_rend_bitstream_read_int32( pBits, ENV0_BITS ); + iLastRMSVal = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ENV0_BITS ); iBitsRead += ENV0_BITS; iLastRMSVal += ENV_MIN; @@ -1405,146 +1642,171 @@ static int32_t ReadRMSEnvelope( static int32_t ReadAllocInformation( int32_t *piAllocOffset, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsRead; iBitsRead = 0; - *piAllocOffset = ivas_split_rend_bitstream_read_int32( pBits, ALLOC_OFFSET_BITS ); + *piAllocOffset = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ALLOC_OFFSET_BITS ); *piAllocOffset += MIN_ALLOC_OFFSET; iBitsRead += ALLOC_OFFSET_BITS; return iBitsRead; } + static int32_t ReadLCLDData( - const int32_t iNumGroups, - const int32_t *piGroupLengths, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t *piPredEnable, - int32_t **ppiAlloc, - int32_t **ppiSignReal, - int32_t **ppiSignImag, - int32_t **ppiQReal, - int32_t **ppiQImag, - IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t iNumChannels, + int32_t **ppiDecodingUnresolved, + int32_t **ppiPredEnable, + const int32_t iNumSubSets, + const int32_t iSubSetId, + int32_t ***pppiAlloc, + int32_t ***pppiSignReal, + int32_t ***pppiSignImag, + int32_t ***pppiQReal, + int32_t ***pppiQImag, + int32_t **ppiDecodingFailed, + ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) { - int32_t b, k, m, n; - int32_t iBitsRead, iBlockOffest, iFBOffset; - int32_t iAlloc, iHuffDim, iHuffMod; + int32_t iBitsRead; + int32_t iDecodingStopped = 0; + int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + int32_t s; + int32_t iSet = iSubSetId; iBitsRead = 0; - iBlockOffest = 0; - for ( n = 0; n < iNumGroups; n++ ) + for ( s = 0; s < iNumSubSets; s++, iSet-- ) { - for ( k = 0; k < piGroupLengths[n]; k++ ) + int32_t ch; + + if ( iSet < 0 ) { - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - iAlloc = ppiAlloc[n][b]; + iSet = iNumSubSets - 1; + } - iHuffDim = c_aiHuffmanDim[iAlloc]; - iHuffMod = c_aiHuffmanMod[iAlloc]; + for ( ch = 0; ch < iNumChannels; ch++ ) + { + int32_t n; + int32_t iBlockOffest; - if ( iAlloc > 0 ) + if ( ppiDecodingUnresolved[ch][iSet] == 1 ) + { + iDecodingStopped = 1; + ppiDecodingFailed[ch][iSet] = 1; /* mark as not decoded (is also initialized like that when a frame is lost */ + } + else + { + ppiDecodingFailed[ch][iSet] = 0; /* mark as correctly decoded */ + } + iBlockOffest = 0; + for ( n = 0; n < piNumGroups[ch]; n++ ) + { + int32_t k; + for ( k = 0; k < ppiGroupLengths[ch][n]; k++ ) { - const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; - const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; -#ifdef USE_DEMOD_TABLES - const int32_t( *paiDemodTable )[2] = NULL; -#endif - pauiHuffmanTable = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc]; - pauiHuffmanTableDPCM = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; -#ifdef USE_DEMOD_TABLES - paiDemodTable = c_apaiDemodTables[iAlloc]; -#endif - for ( m = 0; m < piBandwidths[b]; m++ ) + int32_t iFBOffset; + + for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) { - int32_t iQuantValue1 = 0; - int32_t iQuantValue2 = 0; + int32_t b; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; - if ( piPredEnable[iFBOffset] == 1 ) + b = c_aiBandIdPerLcldBand[iFBOffset]; + + iAlloc = pppiAlloc[ch][n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iDecodingStopped == 1 ) { - if ( iHuffDim == 2 ) - { - int32_t iSymbol; - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); -#ifdef USE_DEMOD_TABLES - iQuantValue1 = paiDemodTable[iSymbol][0]; - iQuantValue2 = paiDemodTable[iSymbol][1]; + pppiQReal[ch][iBlockOffest][iFBOffset] = 0; + pppiQImag[ch][iBlockOffest][iFBOffset] = 0; + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + } + else if ( iAlloc > 0 ) + { + const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; + const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; + int32_t iQuantValue1 = 0; + int32_t iQuantValue2 = 0; + pauiHuffmanTable = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc]; + pauiHuffmanTableDPCM = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; +#ifdef LCLD_HANDLE_PRED_START_SAMPLE + if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) #else - iQuantValue1 = iSymbol / iHuffMod; - iQuantValue2 = iSymbol % iHuffMod; + if ( ppiPredEnable[ch][iFBOffset] == 1 ) #endif + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; + } + else + { + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ); + } } else { - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ); - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ); + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + + iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits ); + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; + } + else + { + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ); + } } - } - else - { - if ( iHuffDim == 2 ) - { - int32_t iSymbol; - iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits ); -#ifdef USE_DEMOD_TABLES - iQuantValue1 = paiDemodTable[iSymbol][0]; - iQuantValue2 = paiDemodTable[iSymbol][1]; -#else - iQuantValue1 = iSymbol / iHuffMod; - iQuantValue2 = iSymbol % iHuffMod; -#endif + pppiQReal[ch][iBlockOffest][iFBOffset] = iQuantValue1; + pppiQImag[ch][iBlockOffest][iFBOffset] = iQuantValue2; + + if ( iQuantValue1 > 0 ) + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; } else { - iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); - iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ); + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + } + if ( iQuantValue2 > 0 ) + { + pppiSignImag[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + else + { + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; } - } - - ppiQReal[iBlockOffest][iFBOffset] = iQuantValue1; - ppiQImag[iBlockOffest][iFBOffset] = iQuantValue2; - - if ( iQuantValue1 > 0 ) - { - ppiSignReal[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - else - { - ppiSignReal[iBlockOffest][iFBOffset] = 0; - } - if ( iQuantValue2 > 0 ) - { - ppiSignImag[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; } else { - ppiSignImag[iBlockOffest][iFBOffset] = 0; + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; } - - iFBOffset++; - } - } - else - { - for ( m = 0; m < piBandwidths[b]; m++ ) - { - ppiSignReal[iBlockOffest][iFBOffset] = 0; - ppiSignImag[iBlockOffest][iFBOffset] = 0; - iFBOffset++; } + iBlockOffest++; } } - - iBlockOffest++; } } @@ -1578,4 +1840,3 @@ static void ComputeAllocation( return; } -#endif diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_isar/isar_lcld_encoder.c similarity index 83% rename from lib_rend/ivas_lcld_encoder.c rename to lib_isar/isar_lcld_encoder.c index 4ad176ec0dcd9a5e06527ae5deff400aa6ca6acf..5a5f743c8bbda0997600980c7e90bf5beb860fc1 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_isar/isar_lcld_encoder.c @@ -32,13 +32,10 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" #include "prot.h" -#include "ivas_prot_rend.h" +#include "isar_prot.h" #include "wmc_auto.h" /*------------------------------------------------------------------------------------------* @@ -62,6 +59,7 @@ struct LCLD_ENCODER int32_t piLRPhaseDiffs[MAX_BANDS]; int32_t iAllowSidePred; + int32_t iRealOnlyOut; RMSEnvelopeGrouping *psRMSEnvelopeGrouping; @@ -81,10 +79,10 @@ struct LCLD_ENCODER int32_t ***pppiQLCLDReal; int32_t ***pppiQLCLDImag; - PredictionEncoder *psPredictionEncoder; }; + /*------------------------------------------------------------------------------------------* * Function Quantize() * @@ -98,6 +96,7 @@ static int32_t Quantize( const int32_t iMaxVal ) { int32_t iVal; + if ( fVal > 0.0f ) { iVal = (int32_t) ( fScale * fVal + 0.5f ); @@ -113,6 +112,7 @@ static int32_t Quantize( return iVal; } + /*------------------------------------------------------------------------------------------* * Function UnQuantize() * @@ -125,6 +125,7 @@ static float UnQuantize( const int32_t iSign ) { float fVal; + if ( iSign == 0 ) { fVal = fScale * (float) iVal; @@ -133,9 +134,36 @@ static float UnQuantize( { fVal = -fScale * (float) iVal; } + return fVal; } + +static void PackReal( + const int32_t iChannels, + const int32_t iNumBlocks, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t ch, b, n; + + for ( ch = 0; ch < iChannels; ch++ ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + int32_t iRealBlock = 0; + for ( n = 0; n < iNumBlocks; n += 2 ) + { + pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b]; + pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b]; + iRealBlock++; + } + } + } + + return; +} + /*------------------------------------------------------------------------------------------* * Function CreateLCLDEncoder() * @@ -149,14 +177,15 @@ ivas_error CreateLCLDEncoder( const int32_t iTargetBitRate, const int32_t iAllowSidePred, const int16_t iNumBlocks, - const int16_t iNumSubSets ) + const int16_t iNumSubSets, + const int32_t iRealOnlyOut ) { int32_t n; LCLDEncoder *psLCLDEncoder; ivas_error error; int32_t iMaxNumPredBands = 0; - assert( iSampleRate == 48000 ); // Fix + assert( iSampleRate == 48000 ); assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS ); @@ -167,20 +196,26 @@ ivas_error CreateLCLDEncoder( psLCLDEncoder->iSampleRate = iSampleRate; psLCLDEncoder->iChannels = iChannels; - psLCLDEncoder->iNumBlocks = (int32_t) iNumBlocks; + psLCLDEncoder->iRealOnlyOut = iRealOnlyOut; psLCLDEncoder->iAllocOffset = 0; psLCLDEncoder->iTargetBitRate = iTargetBitRate; psLCLDEncoder->piBandwidths = c_aiBandwidths48; psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */ - for ( n = 0; n < psLCLDEncoder->iNumBands; n++ ) + iMaxNumPredBands = min( c_aiNumLcldBandsPerBand[psLCLDEncoder->iNumBands - 1], 50 ); + if ( iRealOnlyOut == 1 ) { - iMaxNumPredBands += psLCLDEncoder->piBandwidths[n]; + iMaxNumPredBands = 0; + assert( iNumSubSets == 1 ); + psLCLDEncoder->iNumBlocks = iNumBlocks / 2; + } + else + { + psLCLDEncoder->iNumBlocks = iNumBlocks; } - - psLCLDEncoder->iMSMode = 0; + if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -192,10 +227,9 @@ ivas_error CreateLCLDEncoder( psLCLDEncoder->piMSPredCoefs[n] = 0; } psLCLDEncoder->iAllowSidePred = iAllowSidePred; - psLCLDEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psLCLDEncoder->iNumBlocks ); - psLCLDEncoder->iCommonGrouping = 1; //*Common grouping always on only impacts stereo */ + psLCLDEncoder->iCommonGrouping = 1; /*Common grouping always on only impacts stereo */ if ( ( psLCLDEncoder->piNumGroups = (int32_t *) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -226,7 +260,6 @@ ivas_error CreateLCLDEncoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignReal = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -247,7 +280,6 @@ ivas_error CreateLCLDEncoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( n = 0; n < iChannels; n++ ) { int32_t k; @@ -390,6 +422,7 @@ void DeleteLCLDEncoder( } free( psLCLDEncoder->ppiGroupLengths ); } + if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) { for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) @@ -501,30 +534,32 @@ void DeleteLCLDEncoder( return; } + /*------------------------------------------------------------------------------------------* * Local function declarations *------------------------------------------------------------------------------------------*/ -static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piMSMode, int32_t *piLRPhaseDiff, int32_t *piMSPredCoef, const int32_t iAllowSidePred, int32_t *piMSFlags ); +static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piMSMode, int32_t *piLRPhaseDiff, int32_t *piMSPredCoef, const int32_t iAllowSidePred, const int32_t iRealOnlyOut, int32_t *piMSFlags ); static void RemoveRMSEnvelope( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, float **ppfReal, float **ppfImag ); static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag ); -static int32_t WriteHeaderInformation( const int32_t iNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t WriteHeaderInformation( const int32_t iNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, int32_t iNumMSPredBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, const int32_t iNumMSPredBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t WriteAllocInformation( const int32_t iAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t WriteLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, IVAS_SPLIT_REND_BITS_HANDLE pBits ); +static int32_t WriteLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, ISAR_SPLIT_REND_BITS_HANDLE pBits ); static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); + /*------------------------------------------------------------------------------------------* * Function EncodeLCLDFrame() * @@ -537,15 +572,22 @@ int32_t EncodeLCLDFrame( float ***pppfLCLDImag, int32_t *piBitsWritten, const int32_t available_bits, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t n; + int32_t k, n; int32_t iAvailableBits, iBitsWritten; int32_t iNumMSBands = 0; - iAvailableBits = available_bits; // HCBR for now + int32_t iAudioBitsWritten; + + iAvailableBits = available_bits; /* HCBR for now*/ iBitsWritten = 0; assert( available_bits <= pBits->buf_len * 8 ); + if ( psLCLDEncoder->iRealOnlyOut == 1 ) + { + PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal, pppfLCLDImag ); + } + /* Do MS calc here */ if ( psLCLDEncoder->iChannels == 2 ) { @@ -558,15 +600,15 @@ int32_t EncodeLCLDFrame( psLCLDEncoder->piLRPhaseDiffs, psLCLDEncoder->piMSPredCoefs, psLCLDEncoder->iAllowSidePred, + psLCLDEncoder->iRealOnlyOut, psLCLDEncoder->piMSFlags ); if ( psLCLDEncoder->iMSMode > 0 ) { - psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use + psLCLDEncoder->iCommonGrouping = 1; /* Make sure common grouping is enabled when MS is in use */ } } - /* Compute Grouping and RMS Envelopes */ if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) { @@ -628,17 +670,14 @@ int32_t EncodeLCLDFrame( pBits ); } - iBitsWritten += WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ); iBitsWritten += WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ); iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); - if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) { - int32_t k; for ( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ ) { PerceptualModelStereo( psLCLDEncoder->iNumBands, @@ -655,7 +694,6 @@ int32_t EncodeLCLDFrame( { for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - int32_t k; for ( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) { PerceptualModel( psLCLDEncoder->iNumBands, @@ -679,6 +717,7 @@ int32_t EncodeLCLDFrame( fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] ); } #endif + iAvailableBits -= iBitsWritten; ComputeAllocation( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, @@ -697,38 +736,28 @@ int32_t EncodeLCLDFrame( psLCLDEncoder->pppiLCLDSignImag, psLCLDEncoder->psPredictionEncoder ); - iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, - pBits ); - - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups[n], - (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - (const int32_t *) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n], - psLCLDEncoder->pppiAlloc[n], - psLCLDEncoder->pppiLCLDSignReal[n], - psLCLDEncoder->pppiLCLDSignImag[n], - psLCLDEncoder->pppiQLCLDReal[n], - psLCLDEncoder->pppiQLCLDImag[n], - pBits ); - } + iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, pBits ); + + iAudioBitsWritten = iBitsWritten; + iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups, + psLCLDEncoder->ppiGroupLengths, + psLCLDEncoder->iNumBands, + psLCLDEncoder->iChannels, + psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, + psLCLDEncoder->psPredictionEncoder->iNumSubSets, + psLCLDEncoder->psPredictionEncoder->iSubSetId, + psLCLDEncoder->pppiAlloc, + psLCLDEncoder->pppiLCLDSignReal, + psLCLDEncoder->pppiLCLDSignImag, + psLCLDEncoder->pppiQLCLDReal, + psLCLDEncoder->pppiQLCLDImag, + pBits ); *piBitsWritten = iBitsWritten; + iAudioBitsWritten = iBitsWritten - iAudioBitsWritten; - return 0; -} - - -/*------------------------------------------------------------------------------------------* - * Function GetNumGroups() - * - * - *------------------------------------------------------------------------------------------*/ + UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder ); -int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder ) -{ - return psLCLDEncoder->piNumGroups[0]; + return 0; } @@ -763,6 +792,7 @@ static int32_t MSModeCalculation( int32_t *piLRPhaseDiffs, int32_t *piMSPredCoefs, const int32_t iAllowSidePred, + const int32_t iRealOnlyOut, int32_t *piMSFlags ) { int32_t b; @@ -770,25 +800,39 @@ static int32_t MSModeCalculation( int32_t iNumMSBands; int32_t iMSPredType; float fMSBitGain = 0.0f; - float pfMSPredBitGain[3] = { 0.0f }; + float pfMSPredBitGain[3]; float fPred; - int32_t piMSPredFlags0[MAX_BANDS] = { 0 }; - int32_t piMSPredFlags1[MAX_BANDS] = { 0 }; - int32_t piMSPredFlags2[MAX_BANDS] = { 0 }; + int32_t piMSPredFlags0[MAX_BANDS]; + int32_t piMSPredFlags1[MAX_BANDS]; + int32_t piMSPredFlags2[MAX_BANDS]; int32_t *ppiMSPredFlags[3]; - int32_t piMSPredCoefs0[MAX_BANDS] = { 0 }; - int32_t piMSPredCoefs1[MAX_BANDS] = { 0 }; - int32_t piMSPredCoefs2[MAX_BANDS] = { 0 }; + int32_t piMSPredCoefs0[MAX_BANDS]; + int32_t piMSPredCoefs1[MAX_BANDS]; + int32_t piMSPredCoefs2[MAX_BANDS]; int32_t *ppiMSPredCoefs[3]; - int32_t piMSPredPhase0[MAX_BANDS] = { 0 }; - int32_t piMSPredPhase1[MAX_BANDS] = { 0 }; - int32_t piMSPredPhase2[MAX_BANDS] = { 0 }; + int32_t piMSPredPhase0[MAX_BANDS]; + int32_t piMSPredPhase1[MAX_BANDS]; + int32_t piMSPredPhase2[MAX_BANDS]; int32_t *ppiMSPredPhase[3]; int32_t iMsInfoBits; - int32_t piMsPredInfoBits[3] = { 0 }; + int32_t piMsPredInfoBits[3]; const float feps = 1e-12f; float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ + + set_zero( pfMSPredBitGain, 3 ); + set_l( piMsPredInfoBits, 0, 3 ); + + set_l( piMSPredFlags0, 0, MAX_BANDS ); + set_l( piMSPredFlags1, 0, MAX_BANDS ); + set_l( piMSPredFlags2, 0, MAX_BANDS ); + set_l( piMSPredCoefs0, 0, MAX_BANDS ); + set_l( piMSPredCoefs1, 0, MAX_BANDS ); + set_l( piMSPredCoefs2, 0, MAX_BANDS ); + set_l( piMSPredPhase0, 0, MAX_BANDS ); + set_l( piMSPredPhase1, 0, MAX_BANDS ); + set_l( piMSPredPhase2, 0, MAX_BANDS ); + if ( iNumBlocks < LCLD_BLOCKS_PER_FRAME ) { fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */ @@ -826,8 +870,8 @@ static int32_t MSModeCalculation( int32_t iPhase; int32_t iPred; int32_t tabIdx = 0; - float fNumLines = (float) ( iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */ - float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ + float fNumLines = (float) ( iRealOnlyOut == 1 ? iNumBlocks * piBandwidths[b] * 4 : iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */ + float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ fLeftEnergy = 0.0f; fRightEnergy = 0.0f; fMidEnergy = 0.0f; @@ -880,7 +924,7 @@ static int32_t MSModeCalculation( /* adjust covariance */ tabIdx = iPhase - PHASE_MIN_VAL; - cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); + cplxmult_lcld( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); /* compute MS prediction coefficient based on adjusted covariance */ fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); @@ -942,9 +986,16 @@ static int32_t MSModeCalculation( } /* find the best M/S Pred type */ - iMSPredType = MS_PHASE_AND_PRED; - iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); - iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + if ( iRealOnlyOut == 1 ) + { + iMSPredType = MS_PRED_ONLY; + } + else + { + iMSPredType = MS_PHASE_AND_PRED; + iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + } /* plain M/S */ iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL ); @@ -990,6 +1041,7 @@ static int32_t MSModeCalculation( fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits ); } #endif + if ( *piMSMode != MS_OFF ) { iFBOffset = 0; @@ -1013,7 +1065,7 @@ static int32_t MSModeCalculation( if ( *piMSMode == MS_PRED ) { - cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); + cplxmult_lcld( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); } fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); @@ -1108,6 +1160,7 @@ static void RemoveRMSEnvelope( return; } + static void QuantizeSpectrumDPCM_Opt( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1120,9 +1173,9 @@ static void QuantizeSpectrumDPCM_Opt( int32_t **ppiQImag, int32_t **ppiSignReal, int32_t **ppiSignImag, - int32_t iNumSubSets, - int32_t iSubSetId, - int32_t *piPredEnable, + const int32_t iNumSubSets, + const int32_t iSubSetId, + const int32_t *piPredEnable, float *pfA1Real, float *pfA1Imag, float *pfPredStateReal, @@ -1218,8 +1271,11 @@ static void QuantizeSpectrumDPCM_Opt( iFBOffset++; } /* bandwidth */ } /* bands */ + + return; } + static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1252,8 +1308,10 @@ static int32_t CountLCLDBits( { const uint16_t( *pauiHuffmanTable )[2] = NULL; const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) { int32_t iQuantValue1; @@ -1314,12 +1372,12 @@ static int32_t CountLCLDBits( /* Currently only the number of bands in frame */ static int32_t WriteHeaderInformation( const int32_t iNumBands, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsWritten; iBitsWritten = 0; - ivas_split_rend_bitstream_write_int32( pBits, iNumBands, 5 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 ); iBitsWritten += 5; return iBitsWritten; @@ -1332,21 +1390,22 @@ static int32_t WriteMSInformation( const int32_t *piMSFlags, const int32_t *piLRPhaseDiff, const int32_t *piMSPredCoef, - int32_t iNumMSPredBands, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + const int32_t iNumMSPredBands, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsWritten; int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); #ifdef DEBUG_WRITE_MS_PRED int32_t iBitsWrittenTmp = 0; #endif + iBitsWritten = 0; - ivas_split_rend_bitstream_write_int32( pBits, iMSMode, 2 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 ); iBitsWritten += 2; if ( iMSMode == 3 ) { - ivas_split_rend_bitstream_write_int32( pBits, iMSPredAll, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 ); iBitsWritten += 1; } @@ -1355,7 +1414,7 @@ static int32_t WriteMSInformation( int32_t n; for ( n = 0; n < iNumBands; n++ ) { - ivas_split_rend_bitstream_write_int32( pBits, piMSFlags[n], 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 ); iBitsWritten += 1; } } @@ -1376,17 +1435,18 @@ static int32_t WriteMSInformation( break; } } - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); iBitsWritten++; if ( anyNonZero ) { - ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); iBitsWritten += PHASE_BAND0_BITS; for ( b = 1; b < iNumMSPredBands; b++ ) { int32_t tabIdx = piLRPhaseDiff[b] - ENV_DELTA_MIN; - ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; } } @@ -1401,17 +1461,17 @@ static int32_t WriteMSInformation( } } - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); iBitsWritten++; if ( anyNonZero ) { - ivas_split_rend_bitstream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS ); iBitsWritten += PRED_BAND0_BITS; for ( b = 1; b < iNumMSPredBands; b++ ) { int32_t tabIdx = piMSPredCoef[b] - ENV_DELTA_MIN; - ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; } } @@ -1436,33 +1496,33 @@ static int32_t WriteGroupInformation( const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t c, k, n, iBitsWritten; iBitsWritten = 0; if ( iChannels == 2 && iCommonGrouping == 1 ) { - ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); iBitsWritten += 1; for ( n = 0; n < piNumGroups[0]; n++ ) { for ( k = 1; k < ppiGroupLengths[0][n]; k++ ) { - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); iBitsWritten += 1; } if ( n < ( piNumGroups[0] - 1 ) ) { - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); iBitsWritten += 1; } } } else if ( iChannels == 2 ) { - ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); iBitsWritten += 1; for ( c = 0; c < iChannels; c++ ) @@ -1471,12 +1531,12 @@ static int32_t WriteGroupInformation( { for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) { - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); iBitsWritten += 1; } if ( n < ( piNumGroups[c] - 1 ) ) { - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); iBitsWritten += 1; } } @@ -1490,13 +1550,13 @@ static int32_t WriteGroupInformation( { for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) { - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); iBitsWritten += 1; } if ( n < ( piNumGroups[c] - 1 ) ) { - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); iBitsWritten += 1; } } @@ -1512,7 +1572,7 @@ static int32_t WriteRMSEnvelope( const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t k, n; int32_t iBitsWritten; @@ -1528,7 +1588,7 @@ static int32_t WriteRMSEnvelope( iLastRMSVal = pppiRMSEnvelope[n][k][0]; iLastRMSVal = ( iLastRMSVal > ENV_MIN ) ? iLastRMSVal : ENV_MIN; iLastRMSVal = ( iLastRMSVal < ENV_MAX ) ? iLastRMSVal : ENV_MAX; - ivas_split_rend_bitstream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS ); iBitsWritten += ENV0_BITS; for ( b = 1; b < iNumBands; b++ ) @@ -1539,7 +1599,7 @@ static int32_t WriteRMSEnvelope( iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; iDelta -= ENV_DELTA_MIN; - ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0]; iLastRMSVal = pppiRMSEnvelope[n][k][b]; @@ -1553,7 +1613,7 @@ static int32_t WriteRMSEnvelope( static int32_t WriteAllocInformation( const int32_t iAllocOffset, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsWritten; @@ -1564,7 +1624,7 @@ static int32_t WriteAllocInformation( printf( "Serious error\n" ); } - ivas_split_rend_bitstream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); iBitsWritten += ALLOC_OFFSET_BITS; return iBitsWritten; @@ -1572,122 +1632,129 @@ static int32_t WriteAllocInformation( static int32_t WriteLCLDData( - const int32_t iNumGroups, - const int32_t *piGroupLengths, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t *piPredEnable, - int32_t **ppiAlloc, - int32_t **ppiSignReal, - int32_t **ppiSignImag, - int32_t **ppiQReal, - int32_t **ppiQImag, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + const int32_t iNumChannels, + int32_t **ppiPredEnable, + const int32_t iNumSubSets, + const int32_t iSubSetId, + int32_t ***pppiAlloc, + int32_t ***pppiSignReal, + int32_t ***pppiSignImag, + int32_t ***pppiQReal, + int32_t ***pppiQImag, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t n; int32_t iBitsWritten; - int32_t iBlockOffest; + int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + int32_t s; + int32_t iSet = iSubSetId; iBitsWritten = 0; - iBlockOffest = 0; - - for ( n = 0; n < iNumGroups; n++ ) + for ( s = 0; s < iNumSubSets; s++, iSet-- ) { - int32_t k; - for ( k = 0; k < piGroupLengths[n]; k++ ) + int32_t ch; + if ( iSet < 0 ) { - int32_t b; - int32_t iFBOffset; + iSet = iNumSubSets - 1; + } - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) + for ( ch = 0; ch < iNumChannels; ch++ ) + { + int32_t iBlockOffest = 0; + int32_t n; + for ( n = 0; n < piNumGroups[ch]; n++ ) { - int32_t m; - int32_t iAlloc; - int32_t iHuffDim; - int32_t iHuffMod; - - iAlloc = ppiAlloc[n][b]; - - iHuffDim = c_aiHuffmanDim[iAlloc]; - iHuffMod = c_aiHuffmanMod[iAlloc]; - - if ( iAlloc > 0 ) + int32_t k; + for ( k = 0; k < ppiGroupLengths[ch][n]; k++ ) { - const uint16_t( *pauiHuffmanTable )[2] = NULL; - const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; - pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; - pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; - for ( m = 0; m < piBandwidths[b]; m++ ) + int32_t iFBOffset; + for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) { - int32_t iQuantValue1; - int32_t iQuantValue2; + int32_t b; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; - iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; - iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + b = c_aiBandIdPerLcldBand[iFBOffset]; - if ( piPredEnable[iFBOffset] == 1 ) + iAlloc = pppiAlloc[ch][n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) { - if ( iHuffDim == 2 ) + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + int32_t iQuantValue1; + int32_t iQuantValue2; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + + iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset]; + iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset]; +#ifdef LCLD_HANDLE_PRED_START_SAMPLE + if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) +#else + if ( ppiPredEnable[ch][iFBOffset] == 1 ) +#endif { - int32_t iSymbol; - iSymbol = iQuantValue1; - iSymbol *= iHuffMod; - iSymbol += iQuantValue2; - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; + } + else + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; + } } else { - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; - - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); + iBitsWritten += pauiHuffmanTable[iSymbol][0]; + } + else + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; + } } - } - else - { - if ( iHuffDim == 2 ) + + if ( iQuantValue1 > 0 ) { - int32_t iSymbol; - iSymbol = iQuantValue1; - iSymbol *= iHuffMod; - iSymbol += iQuantValue2; - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); - iBitsWritten += pauiHuffmanTable[iSymbol][0]; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; } - else + if ( iQuantValue2 > 0 ) { - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); - iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; - - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); - iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; } } - - if ( iQuantValue1 > 0 ) - { - ivas_split_rend_bitstream_write_int32( pBits, ppiSignReal[iBlockOffest][iFBOffset], 1 ); - iBitsWritten += 1; - } - if ( iQuantValue2 > 0 ) - { - ivas_split_rend_bitstream_write_int32( pBits, ppiSignImag[iBlockOffest][iFBOffset], 1 ); - iBitsWritten += 1; - } - - iFBOffset++; } - } - else - { - iFBOffset += piBandwidths[b]; + iBlockOffest++; } } - - iBlockOffest++; } } @@ -1785,7 +1852,7 @@ static int32_t ComputeAllocation( #ifdef DEBUG_VERBOSE printf( "Frame can not be coded with the number of bits available\n" ); #endif - // iLastError = ENC_ERROR_STREAM_FAILURE; + /* iLastError = ENC_ERROR_STREAM_FAILURE;*/ return -1; } else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits ) @@ -1828,17 +1895,15 @@ static int32_t ComputeAllocation( mvr2r( psPredictionEncoder->ppfPredStateRealTmp[n], psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); mvr2r( psPredictionEncoder->ppfPredStateImagTmp[n], psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); } - if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) - { - psPredictionEncoder->iSubSetId = 0; - } } - // printf("%d\n",*piAllocOffset); - // printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); - - // printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed); +#ifdef DEBUGGING + /* + printf("%d\n",*piAllocOffset); + printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); + printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed); + */ +#endif return iBitsUsed; } -#endif diff --git a/lib_rend/ivas_lcld_prot.h b/lib_isar/isar_lcld_prot.h similarity index 86% rename from lib_rend/ivas_lcld_prot.h rename to lib_isar/isar_lcld_prot.h index 6fbc250fcc73c9119b951be53c681c855c8ec5ca..f87353309927e48edcb8e7e151fc008796deb202 100644 --- a/lib_rend/ivas_lcld_prot.h +++ b/lib_isar/isar_lcld_prot.h @@ -30,13 +30,12 @@ *******************************************************************************************************/ -#ifndef _IVAS_LCLD_ENCODER_H_ -#define _IVAS_LCLD_ENCODER_H_ +#ifndef ISAR_LCLD_PROT_H +#define ISAR_LCLD_PROT_H #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "lib_rend.h" -#include "ivas_lcld_rom_tables.h" +#include "common_api_types.h" +#include "isar_rom_lcld_tables.h" /* clang-format off */ @@ -49,7 +48,9 @@ ivas_error CreateLCLDEncoder( const int32_t iTargetBitRate, const int32_t iAllowSidePred, const int16_t iNumBlocks, - const int16_t iNumSubSets ); + const int16_t iNumSubSets, + const int32_t iRealOnlyOut + ); void DeleteLCLDEncoder( LCLDEncoder *psLCLDEncoder @@ -61,11 +62,7 @@ int32_t EncodeLCLDFrame( float ***pppfLCLDImag, int32_t *piNumiBites, const int32_t available_bits, - IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -int32_t GetNumGroups( - LCLDEncoder *psLCLDEncoder -); + ISAR_SPLIT_REND_BITS_HANDLE pBits ); typedef struct LCLD_DECODER LCLDDecoder; @@ -74,7 +71,8 @@ ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, const int32_t iChannels, - const int32_t iNumBlocks ); + const int32_t iNumBlocks, + const int32_t iRealOnlyOut); void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder @@ -82,7 +80,7 @@ void DeleteLCLDDecoder( int32_t DecodeLCLDFrame( LCLDDecoder *psLCLDDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, float ***pppfLCLDReal, float ***pppfLCLDImag ); @@ -96,11 +94,11 @@ int32_t quantPhase( float phase ); -void cplxmult( +void cplxmult_lcld( float *pr1, float *pi1, - float r2, - float i2 + const float r2, + const float i2 ); @@ -238,8 +236,6 @@ typedef struct PREDICTION_ENCODER float **ppfPredStateImagTmp; float **ppfInpPrevReal; /* channels, bands */ float **ppfInpPrevImag; - - float *pfWindow; float pfRxxReal[2]; float pfRxxImag[2]; @@ -252,6 +248,7 @@ typedef struct PREDICTION_ENCODER int32_t **ppiA1Mag; int32_t **ppiA1Phase; + } PredictionEncoder; ivas_error CreatePredictionEncoder( @@ -272,15 +269,10 @@ void ComputePredictors( float ***pppfImag ); -void ApplyForwardPredictors( - PredictionEncoder *psPredictionEncoder, - float ***pppfReal, - float ***pppfImag -); int32_t WritePredictors( PredictionEncoder *psPredictionEncoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits + ISAR_SPLIT_REND_BITS_HANDLE pBits ); typedef struct PREDICTION_DECODER @@ -295,6 +287,11 @@ typedef struct PREDICTION_DECODER int32_t *piPredChanEnable; int32_t **ppiPredBandEnable; + /* PLC_IMPROVEMENT */ + int32_t **ppiDecodingUnresolved; + int32_t **ppiDecodingFailed; + int32_t **ppiDecodingFailedPrev; + float **ppfA1Real; float **ppfA1Imag; @@ -317,11 +314,45 @@ void DeletePredictionDecoder( PredictionDecoder *psPredictionDecoder ); -int32_t ReadPredictors( +int16_t ReadPredictors( PredictionDecoder *psPredictionDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits + ISAR_SPLIT_REND_BITS_HANDLE pBits ); +/* PLC_IMPROVEMENT */ +void UpdatePredictionSubSetId( + PredictionEncoder *psPredictionEncoder); + +void SetDecodingUnresolved( + LCLDDecoder *psLCLDDecoder); + +int16_t AnyDecodingFailedPrev( + LCLDDecoder *psLCLDDecoder); + +int16_t AnyDecodingFailed( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedStatus( + LCLDDecoder *psLCLDDecoder); + +int16_t GetNumSubSets( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedPrevStatus( + LCLDDecoder *psLCLDDecoder); + +void SetDecodingPassed( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingFailedStatus( + PredictionDecoder *psPredictionDecoder); + +int32_t AnyDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + void ApplyInversePredictors( PredictionDecoder *psPredictionDecoder, float ***pppfReal, @@ -356,7 +387,6 @@ void ComputeEnvelopeGrouping( ); -#endif /* clang-format on */ #endif /* _LCLD_ENCODER_H_ */ diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h new file mode 100644 index 0000000000000000000000000000000000000000..d9a37dc136ebaf8a8a591c281e2470d54cf78d25 --- /dev/null +++ b/lib_isar/isar_prot.h @@ -0,0 +1,391 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_PROT_H +#define ISAR_PROT_H + +#include "isar_stat.h" +#include +#include "options.h" +#include "ivas_error.h" +#include "lib_isar_post_rend.h" + + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * General ISAR prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, /* i/o: binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + const int32_t output_Fs +#endif +); + +ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i/o: Split renderer pre-renderer handle */ + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const IVAS_RENDER_FRAMESIZE ivas_frame_size /* i : IVAS frame size */ +); + +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */ +); + +void lc3plusTimeAlignCldfbPoseCorr( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: Binaural signals, real part */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* i/o: Binaural signals, imag. part */ +); + +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t available_bits, /* i : available bit-budget */ + float *in[] /* i/o: PCM in/out buffer */ +); + +/*! r: parameter value */ +int32_t ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t bits /* i : number of bits to be read */ +); + +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t val, /* i : parameter value */ + const int32_t bits /* i : number of bits to be written */ +); + +ivas_error isar_splitBinLCLDEncOpen( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, /* o : ISAR LCLD encoder handle */ + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate, + const int16_t iNumBlocks, + const int16_t iNumIterations +); + +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, /* i/o: ISAR PLC handle */ + const int16_t iNumSubSets +); + +void isar_splitBinRendPLCClose( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC /* i/o: ISAR PLC handle */ +); + +ivas_error isar_splitBinLCLDDecOpen( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */ + const int32_t iSampleRate, + const int16_t iChannels, + const int16_t iNumBlocks, + const int16_t iNumIterations +); + +void isar_splitBinLCLDDecClose( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec /* o : ISAR LCLD decoder handle */ +); + +void isar_splitBinRendPLCsaveState( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations +); + +void isar_splitBinRendPLC_xf( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations, + int32_t **ppiDecodingFailed, + int32_t **ppiDecodingFailedPrev +); + +void isar_splitBinRendPLC( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations, + int32_t **ppiDecodingFailed +); + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void isar_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const char *filename +); + +#endif +void isar_splitBinLCLDDecProcess( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */ + const int16_t bfi /* i : BFI flag */ +); + +void set_fix_rotation_mat( + float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +); + +void isar_splitBinLCLDEncClose( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc /* i/o: ISAR LCLD encoder handle */ +); + +void isar_splitBinLCLDEncProcess( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, /* i/o: ISAR LCLD encoder handle */ + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int32_t available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */ +); + +void set_pose_types( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1],/* o : ISAR pose type */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +); + +void isar_split_rend_init_huff_cfg( + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg +); + +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const int32_t output_Fs /* i : output sampling rate */ +); + +void isar_splitBinPostRendClose( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend /* i/o: binaural post-renderer handle */ +); + +void isar_SplitRenderer_getdiagdiff( + int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const int16_t sign, + const int16_t min_val, + const int16_t max_val +); + +void isar_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t ro_flag, + int16_t *num_quant_strats +); + +void isar_splitBinPostRendMdDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */ +#endif +); + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); + +void isar_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] +); + +void isar_rend_CldfbSplitPostRendProcess( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const IVAS_QUATERNION QuaternionPost, + float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + float output[][L_FRAME48k], + const int16_t cldfb_in_flag +); + +void isar_rend_CldfbSplitPreRendProcess( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t target_md_bits, /* i : ISAR MD bitrate */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t ro_md_flag /* i : real only metadata for yaw flag */ +); + +ivas_error isar_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const int16_t isar_frame_size_ms, /* i : ISAR bit stream frame size in ms */ + const int16_t codec_frame_size_ms, /* i : ISAR frame length in ms */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int16_t max_bands, /* i : CLDFB bands */ + float *in[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t ro_md_flag /* i : real only metadata for yaw flag */ +); + +void isar_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +); + +void isar_renderSplitGetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +); + +int16_t isar_renderSplitGetRot_axisNumBits( + const int16_t dof +); + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const int16_t dof, + const int16_t code +); + +int16_t isar_renderSplitGetCodeFromRot_axis( + const int16_t dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + int16_t *num_bits +); + +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer post-renderer handle */ +); + +void isar_set_split_rend_ht_setup( + SPLIT_REND_WRAPPER *hSplitrend, /* i/o: Split renderer pre-renderer handle */ + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], /* i/o: External orientation in quaternions */ + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] /* o : real-space rotation matrix */ +); + +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, /* i : ISAR pose correction mode */ + const int32_t nChannels, /* i : number of channels */ + const int32_t lc3plus_frame_duration_us /* i : ISAR frame length in us */ +); + +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +); + +/*! r: LCLD codec bitrate */ +int32_t isar_get_lcld_bitrate( + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode /* i : ISAR pose correction mode */ +); + +/*! r: ISAR MD bitrate */ +int32_t isar_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +); + +ivas_error isar_framesize_to_ms( + const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ + int16_t *ms /* o : frame size in ms */ +); + +ivas_error isar_split_rend_choose_default_codec( + ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + int16_t *pIsar_frame_size_ms, /* i/o: pointer to ISAR frame size setting */ + int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t num_subframes /* i : number of subframes */ +); + +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +); + +int32_t get_bit( + const int32_t state, + const int32_t bit_id +); + +/*! r: ISAR audio type */ +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const IVAS_AUDIO_CONFIG config /* i : audio configuration */ +); + +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer pre-renderer handle */ +); + + +/* clang-format on */ + +#endif /* ISAR_PROT_H */ diff --git a/lib_rend/ivas_lcld_rom_tables.c b/lib_isar/isar_rom_lcld_tables.c similarity index 83% rename from lib_rend/ivas_lcld_rom_tables.c rename to lib_isar/isar_rom_lcld_tables.c index c562624ffaba94d69280d904512851bd2b45d386..dcb0f726e3dd55563d60aa3d55867a6cb92f4487 100644 --- a/lib_rend/ivas_lcld_rom_tables.c +++ b/lib_isar/isar_rom_lcld_tables.c @@ -30,15 +30,26 @@ *******************************************************************************************************/ -#include "ivas_lcld_rom_tables.h" +#include "isar_rom_lcld_tables.h" #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "wmc_auto.h" #include "prot.h" -#include "ivas_lcld_prot.h" +#include "isar_lcld_prot.h" /* clang-format off */ +/*----------------------------------------------------------------------* + * ISAR binaural rendering LCLD ROM tables + *-----------------------------------------------------------------------*/ + +const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 24, 27, 31, 37, 43, 50, 60 +}; + +const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, + 18, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22 +}; /* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = @@ -70,7 +81,6 @@ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = { -1.00000000f, 0.00000000f } }; -/* Move this to perceptual model ? */ const int32_t c_aiBandwidths48[MAX_BANDS_48] = { 1, @@ -10934,7763 +10944,6 @@ const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 100, 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, 153, 181 }; -#ifdef USE_DEMOD_TABLES -const int32_t c_aaiHuffDemod1[16][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, -}; - -const int32_t c_aaiHuffDemod2[16][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, -}; - -const int32_t c_aaiHuffDemod3[25][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, -}; - -const int32_t c_aaiHuffDemod4[36][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, -}; - -const int32_t c_aaiHuffDemod5[36][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, -}; - -const int32_t c_aaiHuffDemod6[49][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, -}; - -const int32_t c_aaiHuffDemod7[64][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, -}; - -const int32_t c_aaiHuffDemod8[81][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, -}; - -const int32_t c_aaiHuffDemod9[100][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, -}; - -const int32_t c_aaiHuffDemod10[169][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, -}; - -const int32_t c_aaiHuffDemod11[196][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, -}; - -const int32_t c_aaiHuffDemod12[289][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 0, - 14, - 0, - 15, - 0, - 16, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 1, - 14, - 1, - 15, - 1, - 16, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 2, - 14, - 2, - 15, - 2, - 16, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 3, - 14, - 3, - 15, - 3, - 16, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 4, - 14, - 4, - 15, - 4, - 16, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 5, - 14, - 5, - 15, - 5, - 16, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 6, - 14, - 6, - 15, - 6, - 16, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 7, - 14, - 7, - 15, - 7, - 16, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 8, - 14, - 8, - 15, - 8, - 16, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 9, - 14, - 9, - 15, - 9, - 16, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 10, - 14, - 10, - 15, - 10, - 16, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 11, - 14, - 11, - 15, - 11, - 16, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 12, - 14, - 12, - 15, - 12, - 16, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, - 13, - 14, - 13, - 15, - 13, - 16, - 14, - 0, - 14, - 1, - 14, - 2, - 14, - 3, - 14, - 4, - 14, - 5, - 14, - 6, - 14, - 7, - 14, - 8, - 14, - 9, - 14, - 10, - 14, - 11, - 14, - 12, - 14, - 13, - 14, - 14, - 14, - 15, - 14, - 16, - 15, - 0, - 15, - 1, - 15, - 2, - 15, - 3, - 15, - 4, - 15, - 5, - 15, - 6, - 15, - 7, - 15, - 8, - 15, - 9, - 15, - 10, - 15, - 11, - 15, - 12, - 15, - 13, - 15, - 14, - 15, - 15, - 15, - 16, - 16, - 0, - 16, - 1, - 16, - 2, - 16, - 3, - 16, - 4, - 16, - 5, - 16, - 6, - 16, - 7, - 16, - 8, - 16, - 9, - 16, - 10, - 16, - 11, - 16, - 12, - 16, - 13, - 16, - 14, - 16, - 15, - 16, - 16, -}; - -const int32_t c_aaiHuffDemod13[324][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 0, - 14, - 0, - 15, - 0, - 16, - 0, - 17, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 1, - 14, - 1, - 15, - 1, - 16, - 1, - 17, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 2, - 14, - 2, - 15, - 2, - 16, - 2, - 17, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 3, - 14, - 3, - 15, - 3, - 16, - 3, - 17, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 4, - 14, - 4, - 15, - 4, - 16, - 4, - 17, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 5, - 14, - 5, - 15, - 5, - 16, - 5, - 17, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 6, - 14, - 6, - 15, - 6, - 16, - 6, - 17, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 7, - 14, - 7, - 15, - 7, - 16, - 7, - 17, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 8, - 14, - 8, - 15, - 8, - 16, - 8, - 17, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 9, - 14, - 9, - 15, - 9, - 16, - 9, - 17, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 10, - 14, - 10, - 15, - 10, - 16, - 10, - 17, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 11, - 14, - 11, - 15, - 11, - 16, - 11, - 17, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 12, - 14, - 12, - 15, - 12, - 16, - 12, - 17, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, - 13, - 14, - 13, - 15, - 13, - 16, - 13, - 17, - 14, - 0, - 14, - 1, - 14, - 2, - 14, - 3, - 14, - 4, - 14, - 5, - 14, - 6, - 14, - 7, - 14, - 8, - 14, - 9, - 14, - 10, - 14, - 11, - 14, - 12, - 14, - 13, - 14, - 14, - 14, - 15, - 14, - 16, - 14, - 17, - 15, - 0, - 15, - 1, - 15, - 2, - 15, - 3, - 15, - 4, - 15, - 5, - 15, - 6, - 15, - 7, - 15, - 8, - 15, - 9, - 15, - 10, - 15, - 11, - 15, - 12, - 15, - 13, - 15, - 14, - 15, - 15, - 15, - 16, - 15, - 17, - 16, - 0, - 16, - 1, - 16, - 2, - 16, - 3, - 16, - 4, - 16, - 5, - 16, - 6, - 16, - 7, - 16, - 8, - 16, - 9, - 16, - 10, - 16, - 11, - 16, - 12, - 16, - 13, - 16, - 14, - 16, - 15, - 16, - 16, - 16, - 17, - 17, - 0, - 17, - 1, - 17, - 2, - 17, - 3, - 17, - 4, - 17, - 5, - 17, - 6, - 17, - 7, - 17, - 8, - 17, - 9, - 17, - 10, - 17, - 11, - 17, - 12, - 17, - 13, - 17, - 14, - 17, - 15, - 17, - 16, - 17, - 17, -}; - -const int32_t c_aaiHuffDemod14[400][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 0, - 14, - 0, - 15, - 0, - 16, - 0, - 17, - 0, - 18, - 0, - 19, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 1, - 14, - 1, - 15, - 1, - 16, - 1, - 17, - 1, - 18, - 1, - 19, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 2, - 14, - 2, - 15, - 2, - 16, - 2, - 17, - 2, - 18, - 2, - 19, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 3, - 14, - 3, - 15, - 3, - 16, - 3, - 17, - 3, - 18, - 3, - 19, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 4, - 14, - 4, - 15, - 4, - 16, - 4, - 17, - 4, - 18, - 4, - 19, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 5, - 14, - 5, - 15, - 5, - 16, - 5, - 17, - 5, - 18, - 5, - 19, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 6, - 14, - 6, - 15, - 6, - 16, - 6, - 17, - 6, - 18, - 6, - 19, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 7, - 14, - 7, - 15, - 7, - 16, - 7, - 17, - 7, - 18, - 7, - 19, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 8, - 14, - 8, - 15, - 8, - 16, - 8, - 17, - 8, - 18, - 8, - 19, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 9, - 14, - 9, - 15, - 9, - 16, - 9, - 17, - 9, - 18, - 9, - 19, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 10, - 14, - 10, - 15, - 10, - 16, - 10, - 17, - 10, - 18, - 10, - 19, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 11, - 14, - 11, - 15, - 11, - 16, - 11, - 17, - 11, - 18, - 11, - 19, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 12, - 14, - 12, - 15, - 12, - 16, - 12, - 17, - 12, - 18, - 12, - 19, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, - 13, - 14, - 13, - 15, - 13, - 16, - 13, - 17, - 13, - 18, - 13, - 19, - 14, - 0, - 14, - 1, - 14, - 2, - 14, - 3, - 14, - 4, - 14, - 5, - 14, - 6, - 14, - 7, - 14, - 8, - 14, - 9, - 14, - 10, - 14, - 11, - 14, - 12, - 14, - 13, - 14, - 14, - 14, - 15, - 14, - 16, - 14, - 17, - 14, - 18, - 14, - 19, - 15, - 0, - 15, - 1, - 15, - 2, - 15, - 3, - 15, - 4, - 15, - 5, - 15, - 6, - 15, - 7, - 15, - 8, - 15, - 9, - 15, - 10, - 15, - 11, - 15, - 12, - 15, - 13, - 15, - 14, - 15, - 15, - 15, - 16, - 15, - 17, - 15, - 18, - 15, - 19, - 16, - 0, - 16, - 1, - 16, - 2, - 16, - 3, - 16, - 4, - 16, - 5, - 16, - 6, - 16, - 7, - 16, - 8, - 16, - 9, - 16, - 10, - 16, - 11, - 16, - 12, - 16, - 13, - 16, - 14, - 16, - 15, - 16, - 16, - 16, - 17, - 16, - 18, - 16, - 19, - 17, - 0, - 17, - 1, - 17, - 2, - 17, - 3, - 17, - 4, - 17, - 5, - 17, - 6, - 17, - 7, - 17, - 8, - 17, - 9, - 17, - 10, - 17, - 11, - 17, - 12, - 17, - 13, - 17, - 14, - 17, - 15, - 17, - 16, - 17, - 17, - 17, - 18, - 17, - 19, - 18, - 0, - 18, - 1, - 18, - 2, - 18, - 3, - 18, - 4, - 18, - 5, - 18, - 6, - 18, - 7, - 18, - 8, - 18, - 9, - 18, - 10, - 18, - 11, - 18, - 12, - 18, - 13, - 18, - 14, - 18, - 15, - 18, - 16, - 18, - 17, - 18, - 18, - 18, - 19, - 19, - 0, - 19, - 1, - 19, - 2, - 19, - 3, - 19, - 4, - 19, - 5, - 19, - 6, - 19, - 7, - 19, - 8, - 19, - 9, - 19, - 10, - 19, - 11, - 19, - 12, - 19, - 13, - 19, - 14, - 19, - 15, - 19, - 16, - 19, - 17, - 19, - 18, - 19, - 19, -}; - -const int32_t c_aaiHuffDemod15[576][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 0, - 14, - 0, - 15, - 0, - 16, - 0, - 17, - 0, - 18, - 0, - 19, - 0, - 20, - 0, - 21, - 0, - 22, - 0, - 23, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 1, - 14, - 1, - 15, - 1, - 16, - 1, - 17, - 1, - 18, - 1, - 19, - 1, - 20, - 1, - 21, - 1, - 22, - 1, - 23, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 2, - 14, - 2, - 15, - 2, - 16, - 2, - 17, - 2, - 18, - 2, - 19, - 2, - 20, - 2, - 21, - 2, - 22, - 2, - 23, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 3, - 14, - 3, - 15, - 3, - 16, - 3, - 17, - 3, - 18, - 3, - 19, - 3, - 20, - 3, - 21, - 3, - 22, - 3, - 23, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 4, - 14, - 4, - 15, - 4, - 16, - 4, - 17, - 4, - 18, - 4, - 19, - 4, - 20, - 4, - 21, - 4, - 22, - 4, - 23, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 5, - 14, - 5, - 15, - 5, - 16, - 5, - 17, - 5, - 18, - 5, - 19, - 5, - 20, - 5, - 21, - 5, - 22, - 5, - 23, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 6, - 14, - 6, - 15, - 6, - 16, - 6, - 17, - 6, - 18, - 6, - 19, - 6, - 20, - 6, - 21, - 6, - 22, - 6, - 23, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 7, - 14, - 7, - 15, - 7, - 16, - 7, - 17, - 7, - 18, - 7, - 19, - 7, - 20, - 7, - 21, - 7, - 22, - 7, - 23, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 8, - 14, - 8, - 15, - 8, - 16, - 8, - 17, - 8, - 18, - 8, - 19, - 8, - 20, - 8, - 21, - 8, - 22, - 8, - 23, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 9, - 14, - 9, - 15, - 9, - 16, - 9, - 17, - 9, - 18, - 9, - 19, - 9, - 20, - 9, - 21, - 9, - 22, - 9, - 23, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 10, - 14, - 10, - 15, - 10, - 16, - 10, - 17, - 10, - 18, - 10, - 19, - 10, - 20, - 10, - 21, - 10, - 22, - 10, - 23, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 11, - 14, - 11, - 15, - 11, - 16, - 11, - 17, - 11, - 18, - 11, - 19, - 11, - 20, - 11, - 21, - 11, - 22, - 11, - 23, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 12, - 14, - 12, - 15, - 12, - 16, - 12, - 17, - 12, - 18, - 12, - 19, - 12, - 20, - 12, - 21, - 12, - 22, - 12, - 23, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, - 13, - 14, - 13, - 15, - 13, - 16, - 13, - 17, - 13, - 18, - 13, - 19, - 13, - 20, - 13, - 21, - 13, - 22, - 13, - 23, - 14, - 0, - 14, - 1, - 14, - 2, - 14, - 3, - 14, - 4, - 14, - 5, - 14, - 6, - 14, - 7, - 14, - 8, - 14, - 9, - 14, - 10, - 14, - 11, - 14, - 12, - 14, - 13, - 14, - 14, - 14, - 15, - 14, - 16, - 14, - 17, - 14, - 18, - 14, - 19, - 14, - 20, - 14, - 21, - 14, - 22, - 14, - 23, - 15, - 0, - 15, - 1, - 15, - 2, - 15, - 3, - 15, - 4, - 15, - 5, - 15, - 6, - 15, - 7, - 15, - 8, - 15, - 9, - 15, - 10, - 15, - 11, - 15, - 12, - 15, - 13, - 15, - 14, - 15, - 15, - 15, - 16, - 15, - 17, - 15, - 18, - 15, - 19, - 15, - 20, - 15, - 21, - 15, - 22, - 15, - 23, - 16, - 0, - 16, - 1, - 16, - 2, - 16, - 3, - 16, - 4, - 16, - 5, - 16, - 6, - 16, - 7, - 16, - 8, - 16, - 9, - 16, - 10, - 16, - 11, - 16, - 12, - 16, - 13, - 16, - 14, - 16, - 15, - 16, - 16, - 16, - 17, - 16, - 18, - 16, - 19, - 16, - 20, - 16, - 21, - 16, - 22, - 16, - 23, - 17, - 0, - 17, - 1, - 17, - 2, - 17, - 3, - 17, - 4, - 17, - 5, - 17, - 6, - 17, - 7, - 17, - 8, - 17, - 9, - 17, - 10, - 17, - 11, - 17, - 12, - 17, - 13, - 17, - 14, - 17, - 15, - 17, - 16, - 17, - 17, - 17, - 18, - 17, - 19, - 17, - 20, - 17, - 21, - 17, - 22, - 17, - 23, - 18, - 0, - 18, - 1, - 18, - 2, - 18, - 3, - 18, - 4, - 18, - 5, - 18, - 6, - 18, - 7, - 18, - 8, - 18, - 9, - 18, - 10, - 18, - 11, - 18, - 12, - 18, - 13, - 18, - 14, - 18, - 15, - 18, - 16, - 18, - 17, - 18, - 18, - 18, - 19, - 18, - 20, - 18, - 21, - 18, - 22, - 18, - 23, - 19, - 0, - 19, - 1, - 19, - 2, - 19, - 3, - 19, - 4, - 19, - 5, - 19, - 6, - 19, - 7, - 19, - 8, - 19, - 9, - 19, - 10, - 19, - 11, - 19, - 12, - 19, - 13, - 19, - 14, - 19, - 15, - 19, - 16, - 19, - 17, - 19, - 18, - 19, - 19, - 19, - 20, - 19, - 21, - 19, - 22, - 19, - 23, - 20, - 0, - 20, - 1, - 20, - 2, - 20, - 3, - 20, - 4, - 20, - 5, - 20, - 6, - 20, - 7, - 20, - 8, - 20, - 9, - 20, - 10, - 20, - 11, - 20, - 12, - 20, - 13, - 20, - 14, - 20, - 15, - 20, - 16, - 20, - 17, - 20, - 18, - 20, - 19, - 20, - 20, - 20, - 21, - 20, - 22, - 20, - 23, - 21, - 0, - 21, - 1, - 21, - 2, - 21, - 3, - 21, - 4, - 21, - 5, - 21, - 6, - 21, - 7, - 21, - 8, - 21, - 9, - 21, - 10, - 21, - 11, - 21, - 12, - 21, - 13, - 21, - 14, - 21, - 15, - 21, - 16, - 21, - 17, - 21, - 18, - 21, - 19, - 21, - 20, - 21, - 21, - 21, - 22, - 21, - 23, - 22, - 0, - 22, - 1, - 22, - 2, - 22, - 3, - 22, - 4, - 22, - 5, - 22, - 6, - 22, - 7, - 22, - 8, - 22, - 9, - 22, - 10, - 22, - 11, - 22, - 12, - 22, - 13, - 22, - 14, - 22, - 15, - 22, - 16, - 22, - 17, - 22, - 18, - 22, - 19, - 22, - 20, - 22, - 21, - 22, - 22, - 22, - 23, - 23, - 0, - 23, - 1, - 23, - 2, - 23, - 3, - 23, - 4, - 23, - 5, - 23, - 6, - 23, - 7, - 23, - 8, - 23, - 9, - 23, - 10, - 23, - 11, - 23, - 12, - 23, - 13, - 23, - 14, - 23, - 15, - 23, - 16, - 23, - 17, - 23, - 18, - 23, - 19, - 23, - 20, - 23, - 21, - 23, - 22, - 23, - 23, -}; - -const int32_t c_aaiHuffDemod16[729][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 0, - 14, - 0, - 15, - 0, - 16, - 0, - 17, - 0, - 18, - 0, - 19, - 0, - 20, - 0, - 21, - 0, - 22, - 0, - 23, - 0, - 24, - 0, - 25, - 0, - 26, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 1, - 14, - 1, - 15, - 1, - 16, - 1, - 17, - 1, - 18, - 1, - 19, - 1, - 20, - 1, - 21, - 1, - 22, - 1, - 23, - 1, - 24, - 1, - 25, - 1, - 26, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 2, - 14, - 2, - 15, - 2, - 16, - 2, - 17, - 2, - 18, - 2, - 19, - 2, - 20, - 2, - 21, - 2, - 22, - 2, - 23, - 2, - 24, - 2, - 25, - 2, - 26, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 3, - 14, - 3, - 15, - 3, - 16, - 3, - 17, - 3, - 18, - 3, - 19, - 3, - 20, - 3, - 21, - 3, - 22, - 3, - 23, - 3, - 24, - 3, - 25, - 3, - 26, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 4, - 14, - 4, - 15, - 4, - 16, - 4, - 17, - 4, - 18, - 4, - 19, - 4, - 20, - 4, - 21, - 4, - 22, - 4, - 23, - 4, - 24, - 4, - 25, - 4, - 26, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 5, - 14, - 5, - 15, - 5, - 16, - 5, - 17, - 5, - 18, - 5, - 19, - 5, - 20, - 5, - 21, - 5, - 22, - 5, - 23, - 5, - 24, - 5, - 25, - 5, - 26, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 6, - 14, - 6, - 15, - 6, - 16, - 6, - 17, - 6, - 18, - 6, - 19, - 6, - 20, - 6, - 21, - 6, - 22, - 6, - 23, - 6, - 24, - 6, - 25, - 6, - 26, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 7, - 14, - 7, - 15, - 7, - 16, - 7, - 17, - 7, - 18, - 7, - 19, - 7, - 20, - 7, - 21, - 7, - 22, - 7, - 23, - 7, - 24, - 7, - 25, - 7, - 26, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 8, - 14, - 8, - 15, - 8, - 16, - 8, - 17, - 8, - 18, - 8, - 19, - 8, - 20, - 8, - 21, - 8, - 22, - 8, - 23, - 8, - 24, - 8, - 25, - 8, - 26, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 9, - 14, - 9, - 15, - 9, - 16, - 9, - 17, - 9, - 18, - 9, - 19, - 9, - 20, - 9, - 21, - 9, - 22, - 9, - 23, - 9, - 24, - 9, - 25, - 9, - 26, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 10, - 14, - 10, - 15, - 10, - 16, - 10, - 17, - 10, - 18, - 10, - 19, - 10, - 20, - 10, - 21, - 10, - 22, - 10, - 23, - 10, - 24, - 10, - 25, - 10, - 26, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 11, - 14, - 11, - 15, - 11, - 16, - 11, - 17, - 11, - 18, - 11, - 19, - 11, - 20, - 11, - 21, - 11, - 22, - 11, - 23, - 11, - 24, - 11, - 25, - 11, - 26, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 12, - 14, - 12, - 15, - 12, - 16, - 12, - 17, - 12, - 18, - 12, - 19, - 12, - 20, - 12, - 21, - 12, - 22, - 12, - 23, - 12, - 24, - 12, - 25, - 12, - 26, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, - 13, - 14, - 13, - 15, - 13, - 16, - 13, - 17, - 13, - 18, - 13, - 19, - 13, - 20, - 13, - 21, - 13, - 22, - 13, - 23, - 13, - 24, - 13, - 25, - 13, - 26, - 14, - 0, - 14, - 1, - 14, - 2, - 14, - 3, - 14, - 4, - 14, - 5, - 14, - 6, - 14, - 7, - 14, - 8, - 14, - 9, - 14, - 10, - 14, - 11, - 14, - 12, - 14, - 13, - 14, - 14, - 14, - 15, - 14, - 16, - 14, - 17, - 14, - 18, - 14, - 19, - 14, - 20, - 14, - 21, - 14, - 22, - 14, - 23, - 14, - 24, - 14, - 25, - 14, - 26, - 15, - 0, - 15, - 1, - 15, - 2, - 15, - 3, - 15, - 4, - 15, - 5, - 15, - 6, - 15, - 7, - 15, - 8, - 15, - 9, - 15, - 10, - 15, - 11, - 15, - 12, - 15, - 13, - 15, - 14, - 15, - 15, - 15, - 16, - 15, - 17, - 15, - 18, - 15, - 19, - 15, - 20, - 15, - 21, - 15, - 22, - 15, - 23, - 15, - 24, - 15, - 25, - 15, - 26, - 16, - 0, - 16, - 1, - 16, - 2, - 16, - 3, - 16, - 4, - 16, - 5, - 16, - 6, - 16, - 7, - 16, - 8, - 16, - 9, - 16, - 10, - 16, - 11, - 16, - 12, - 16, - 13, - 16, - 14, - 16, - 15, - 16, - 16, - 16, - 17, - 16, - 18, - 16, - 19, - 16, - 20, - 16, - 21, - 16, - 22, - 16, - 23, - 16, - 24, - 16, - 25, - 16, - 26, - 17, - 0, - 17, - 1, - 17, - 2, - 17, - 3, - 17, - 4, - 17, - 5, - 17, - 6, - 17, - 7, - 17, - 8, - 17, - 9, - 17, - 10, - 17, - 11, - 17, - 12, - 17, - 13, - 17, - 14, - 17, - 15, - 17, - 16, - 17, - 17, - 17, - 18, - 17, - 19, - 17, - 20, - 17, - 21, - 17, - 22, - 17, - 23, - 17, - 24, - 17, - 25, - 17, - 26, - 18, - 0, - 18, - 1, - 18, - 2, - 18, - 3, - 18, - 4, - 18, - 5, - 18, - 6, - 18, - 7, - 18, - 8, - 18, - 9, - 18, - 10, - 18, - 11, - 18, - 12, - 18, - 13, - 18, - 14, - 18, - 15, - 18, - 16, - 18, - 17, - 18, - 18, - 18, - 19, - 18, - 20, - 18, - 21, - 18, - 22, - 18, - 23, - 18, - 24, - 18, - 25, - 18, - 26, - 19, - 0, - 19, - 1, - 19, - 2, - 19, - 3, - 19, - 4, - 19, - 5, - 19, - 6, - 19, - 7, - 19, - 8, - 19, - 9, - 19, - 10, - 19, - 11, - 19, - 12, - 19, - 13, - 19, - 14, - 19, - 15, - 19, - 16, - 19, - 17, - 19, - 18, - 19, - 19, - 19, - 20, - 19, - 21, - 19, - 22, - 19, - 23, - 19, - 24, - 19, - 25, - 19, - 26, - 20, - 0, - 20, - 1, - 20, - 2, - 20, - 3, - 20, - 4, - 20, - 5, - 20, - 6, - 20, - 7, - 20, - 8, - 20, - 9, - 20, - 10, - 20, - 11, - 20, - 12, - 20, - 13, - 20, - 14, - 20, - 15, - 20, - 16, - 20, - 17, - 20, - 18, - 20, - 19, - 20, - 20, - 20, - 21, - 20, - 22, - 20, - 23, - 20, - 24, - 20, - 25, - 20, - 26, - 21, - 0, - 21, - 1, - 21, - 2, - 21, - 3, - 21, - 4, - 21, - 5, - 21, - 6, - 21, - 7, - 21, - 8, - 21, - 9, - 21, - 10, - 21, - 11, - 21, - 12, - 21, - 13, - 21, - 14, - 21, - 15, - 21, - 16, - 21, - 17, - 21, - 18, - 21, - 19, - 21, - 20, - 21, - 21, - 21, - 22, - 21, - 23, - 21, - 24, - 21, - 25, - 21, - 26, - 22, - 0, - 22, - 1, - 22, - 2, - 22, - 3, - 22, - 4, - 22, - 5, - 22, - 6, - 22, - 7, - 22, - 8, - 22, - 9, - 22, - 10, - 22, - 11, - 22, - 12, - 22, - 13, - 22, - 14, - 22, - 15, - 22, - 16, - 22, - 17, - 22, - 18, - 22, - 19, - 22, - 20, - 22, - 21, - 22, - 22, - 22, - 23, - 22, - 24, - 22, - 25, - 22, - 26, - 23, - 0, - 23, - 1, - 23, - 2, - 23, - 3, - 23, - 4, - 23, - 5, - 23, - 6, - 23, - 7, - 23, - 8, - 23, - 9, - 23, - 10, - 23, - 11, - 23, - 12, - 23, - 13, - 23, - 14, - 23, - 15, - 23, - 16, - 23, - 17, - 23, - 18, - 23, - 19, - 23, - 20, - 23, - 21, - 23, - 22, - 23, - 23, - 23, - 24, - 23, - 25, - 23, - 26, - 24, - 0, - 24, - 1, - 24, - 2, - 24, - 3, - 24, - 4, - 24, - 5, - 24, - 6, - 24, - 7, - 24, - 8, - 24, - 9, - 24, - 10, - 24, - 11, - 24, - 12, - 24, - 13, - 24, - 14, - 24, - 15, - 24, - 16, - 24, - 17, - 24, - 18, - 24, - 19, - 24, - 20, - 24, - 21, - 24, - 22, - 24, - 23, - 24, - 24, - 24, - 25, - 24, - 26, - 25, - 0, - 25, - 1, - 25, - 2, - 25, - 3, - 25, - 4, - 25, - 5, - 25, - 6, - 25, - 7, - 25, - 8, - 25, - 9, - 25, - 10, - 25, - 11, - 25, - 12, - 25, - 13, - 25, - 14, - 25, - 15, - 25, - 16, - 25, - 17, - 25, - 18, - 25, - 19, - 25, - 20, - 25, - 21, - 25, - 22, - 25, - 23, - 25, - 24, - 25, - 25, - 25, - 26, - 26, - 0, - 26, - 1, - 26, - 2, - 26, - 3, - 26, - 4, - 26, - 5, - 26, - 6, - 26, - 7, - 26, - 8, - 26, - 9, - 26, - 10, - 26, - 11, - 26, - 12, - 26, - 13, - 26, - 14, - 26, - 15, - 26, - 16, - 26, - 17, - 26, - 18, - 26, - 19, - 26, - 20, - 26, - 21, - 26, - 22, - 26, - 23, - 26, - 24, - 26, - 25, - 26, - 26, -}; - -const int32_t c_aaiHuffDemod17[729][2] = { - 0, - 0, - 0, - 1, - 0, - 2, - 0, - 3, - 0, - 4, - 0, - 5, - 0, - 6, - 0, - 7, - 0, - 8, - 0, - 9, - 0, - 10, - 0, - 11, - 0, - 12, - 0, - 13, - 0, - 14, - 0, - 15, - 0, - 16, - 0, - 17, - 0, - 18, - 0, - 19, - 0, - 20, - 0, - 21, - 0, - 22, - 0, - 23, - 0, - 24, - 0, - 25, - 0, - 26, - 1, - 0, - 1, - 1, - 1, - 2, - 1, - 3, - 1, - 4, - 1, - 5, - 1, - 6, - 1, - 7, - 1, - 8, - 1, - 9, - 1, - 10, - 1, - 11, - 1, - 12, - 1, - 13, - 1, - 14, - 1, - 15, - 1, - 16, - 1, - 17, - 1, - 18, - 1, - 19, - 1, - 20, - 1, - 21, - 1, - 22, - 1, - 23, - 1, - 24, - 1, - 25, - 1, - 26, - 2, - 0, - 2, - 1, - 2, - 2, - 2, - 3, - 2, - 4, - 2, - 5, - 2, - 6, - 2, - 7, - 2, - 8, - 2, - 9, - 2, - 10, - 2, - 11, - 2, - 12, - 2, - 13, - 2, - 14, - 2, - 15, - 2, - 16, - 2, - 17, - 2, - 18, - 2, - 19, - 2, - 20, - 2, - 21, - 2, - 22, - 2, - 23, - 2, - 24, - 2, - 25, - 2, - 26, - 3, - 0, - 3, - 1, - 3, - 2, - 3, - 3, - 3, - 4, - 3, - 5, - 3, - 6, - 3, - 7, - 3, - 8, - 3, - 9, - 3, - 10, - 3, - 11, - 3, - 12, - 3, - 13, - 3, - 14, - 3, - 15, - 3, - 16, - 3, - 17, - 3, - 18, - 3, - 19, - 3, - 20, - 3, - 21, - 3, - 22, - 3, - 23, - 3, - 24, - 3, - 25, - 3, - 26, - 4, - 0, - 4, - 1, - 4, - 2, - 4, - 3, - 4, - 4, - 4, - 5, - 4, - 6, - 4, - 7, - 4, - 8, - 4, - 9, - 4, - 10, - 4, - 11, - 4, - 12, - 4, - 13, - 4, - 14, - 4, - 15, - 4, - 16, - 4, - 17, - 4, - 18, - 4, - 19, - 4, - 20, - 4, - 21, - 4, - 22, - 4, - 23, - 4, - 24, - 4, - 25, - 4, - 26, - 5, - 0, - 5, - 1, - 5, - 2, - 5, - 3, - 5, - 4, - 5, - 5, - 5, - 6, - 5, - 7, - 5, - 8, - 5, - 9, - 5, - 10, - 5, - 11, - 5, - 12, - 5, - 13, - 5, - 14, - 5, - 15, - 5, - 16, - 5, - 17, - 5, - 18, - 5, - 19, - 5, - 20, - 5, - 21, - 5, - 22, - 5, - 23, - 5, - 24, - 5, - 25, - 5, - 26, - 6, - 0, - 6, - 1, - 6, - 2, - 6, - 3, - 6, - 4, - 6, - 5, - 6, - 6, - 6, - 7, - 6, - 8, - 6, - 9, - 6, - 10, - 6, - 11, - 6, - 12, - 6, - 13, - 6, - 14, - 6, - 15, - 6, - 16, - 6, - 17, - 6, - 18, - 6, - 19, - 6, - 20, - 6, - 21, - 6, - 22, - 6, - 23, - 6, - 24, - 6, - 25, - 6, - 26, - 7, - 0, - 7, - 1, - 7, - 2, - 7, - 3, - 7, - 4, - 7, - 5, - 7, - 6, - 7, - 7, - 7, - 8, - 7, - 9, - 7, - 10, - 7, - 11, - 7, - 12, - 7, - 13, - 7, - 14, - 7, - 15, - 7, - 16, - 7, - 17, - 7, - 18, - 7, - 19, - 7, - 20, - 7, - 21, - 7, - 22, - 7, - 23, - 7, - 24, - 7, - 25, - 7, - 26, - 8, - 0, - 8, - 1, - 8, - 2, - 8, - 3, - 8, - 4, - 8, - 5, - 8, - 6, - 8, - 7, - 8, - 8, - 8, - 9, - 8, - 10, - 8, - 11, - 8, - 12, - 8, - 13, - 8, - 14, - 8, - 15, - 8, - 16, - 8, - 17, - 8, - 18, - 8, - 19, - 8, - 20, - 8, - 21, - 8, - 22, - 8, - 23, - 8, - 24, - 8, - 25, - 8, - 26, - 9, - 0, - 9, - 1, - 9, - 2, - 9, - 3, - 9, - 4, - 9, - 5, - 9, - 6, - 9, - 7, - 9, - 8, - 9, - 9, - 9, - 10, - 9, - 11, - 9, - 12, - 9, - 13, - 9, - 14, - 9, - 15, - 9, - 16, - 9, - 17, - 9, - 18, - 9, - 19, - 9, - 20, - 9, - 21, - 9, - 22, - 9, - 23, - 9, - 24, - 9, - 25, - 9, - 26, - 10, - 0, - 10, - 1, - 10, - 2, - 10, - 3, - 10, - 4, - 10, - 5, - 10, - 6, - 10, - 7, - 10, - 8, - 10, - 9, - 10, - 10, - 10, - 11, - 10, - 12, - 10, - 13, - 10, - 14, - 10, - 15, - 10, - 16, - 10, - 17, - 10, - 18, - 10, - 19, - 10, - 20, - 10, - 21, - 10, - 22, - 10, - 23, - 10, - 24, - 10, - 25, - 10, - 26, - 11, - 0, - 11, - 1, - 11, - 2, - 11, - 3, - 11, - 4, - 11, - 5, - 11, - 6, - 11, - 7, - 11, - 8, - 11, - 9, - 11, - 10, - 11, - 11, - 11, - 12, - 11, - 13, - 11, - 14, - 11, - 15, - 11, - 16, - 11, - 17, - 11, - 18, - 11, - 19, - 11, - 20, - 11, - 21, - 11, - 22, - 11, - 23, - 11, - 24, - 11, - 25, - 11, - 26, - 12, - 0, - 12, - 1, - 12, - 2, - 12, - 3, - 12, - 4, - 12, - 5, - 12, - 6, - 12, - 7, - 12, - 8, - 12, - 9, - 12, - 10, - 12, - 11, - 12, - 12, - 12, - 13, - 12, - 14, - 12, - 15, - 12, - 16, - 12, - 17, - 12, - 18, - 12, - 19, - 12, - 20, - 12, - 21, - 12, - 22, - 12, - 23, - 12, - 24, - 12, - 25, - 12, - 26, - 13, - 0, - 13, - 1, - 13, - 2, - 13, - 3, - 13, - 4, - 13, - 5, - 13, - 6, - 13, - 7, - 13, - 8, - 13, - 9, - 13, - 10, - 13, - 11, - 13, - 12, - 13, - 13, - 13, - 14, - 13, - 15, - 13, - 16, - 13, - 17, - 13, - 18, - 13, - 19, - 13, - 20, - 13, - 21, - 13, - 22, - 13, - 23, - 13, - 24, - 13, - 25, - 13, - 26, - 14, - 0, - 14, - 1, - 14, - 2, - 14, - 3, - 14, - 4, - 14, - 5, - 14, - 6, - 14, - 7, - 14, - 8, - 14, - 9, - 14, - 10, - 14, - 11, - 14, - 12, - 14, - 13, - 14, - 14, - 14, - 15, - 14, - 16, - 14, - 17, - 14, - 18, - 14, - 19, - 14, - 20, - 14, - 21, - 14, - 22, - 14, - 23, - 14, - 24, - 14, - 25, - 14, - 26, - 15, - 0, - 15, - 1, - 15, - 2, - 15, - 3, - 15, - 4, - 15, - 5, - 15, - 6, - 15, - 7, - 15, - 8, - 15, - 9, - 15, - 10, - 15, - 11, - 15, - 12, - 15, - 13, - 15, - 14, - 15, - 15, - 15, - 16, - 15, - 17, - 15, - 18, - 15, - 19, - 15, - 20, - 15, - 21, - 15, - 22, - 15, - 23, - 15, - 24, - 15, - 25, - 15, - 26, - 16, - 0, - 16, - 1, - 16, - 2, - 16, - 3, - 16, - 4, - 16, - 5, - 16, - 6, - 16, - 7, - 16, - 8, - 16, - 9, - 16, - 10, - 16, - 11, - 16, - 12, - 16, - 13, - 16, - 14, - 16, - 15, - 16, - 16, - 16, - 17, - 16, - 18, - 16, - 19, - 16, - 20, - 16, - 21, - 16, - 22, - 16, - 23, - 16, - 24, - 16, - 25, - 16, - 26, - 17, - 0, - 17, - 1, - 17, - 2, - 17, - 3, - 17, - 4, - 17, - 5, - 17, - 6, - 17, - 7, - 17, - 8, - 17, - 9, - 17, - 10, - 17, - 11, - 17, - 12, - 17, - 13, - 17, - 14, - 17, - 15, - 17, - 16, - 17, - 17, - 17, - 18, - 17, - 19, - 17, - 20, - 17, - 21, - 17, - 22, - 17, - 23, - 17, - 24, - 17, - 25, - 17, - 26, - 18, - 0, - 18, - 1, - 18, - 2, - 18, - 3, - 18, - 4, - 18, - 5, - 18, - 6, - 18, - 7, - 18, - 8, - 18, - 9, - 18, - 10, - 18, - 11, - 18, - 12, - 18, - 13, - 18, - 14, - 18, - 15, - 18, - 16, - 18, - 17, - 18, - 18, - 18, - 19, - 18, - 20, - 18, - 21, - 18, - 22, - 18, - 23, - 18, - 24, - 18, - 25, - 18, - 26, - 19, - 0, - 19, - 1, - 19, - 2, - 19, - 3, - 19, - 4, - 19, - 5, - 19, - 6, - 19, - 7, - 19, - 8, - 19, - 9, - 19, - 10, - 19, - 11, - 19, - 12, - 19, - 13, - 19, - 14, - 19, - 15, - 19, - 16, - 19, - 17, - 19, - 18, - 19, - 19, - 19, - 20, - 19, - 21, - 19, - 22, - 19, - 23, - 19, - 24, - 19, - 25, - 19, - 26, - 20, - 0, - 20, - 1, - 20, - 2, - 20, - 3, - 20, - 4, - 20, - 5, - 20, - 6, - 20, - 7, - 20, - 8, - 20, - 9, - 20, - 10, - 20, - 11, - 20, - 12, - 20, - 13, - 20, - 14, - 20, - 15, - 20, - 16, - 20, - 17, - 20, - 18, - 20, - 19, - 20, - 20, - 20, - 21, - 20, - 22, - 20, - 23, - 20, - 24, - 20, - 25, - 20, - 26, - 21, - 0, - 21, - 1, - 21, - 2, - 21, - 3, - 21, - 4, - 21, - 5, - 21, - 6, - 21, - 7, - 21, - 8, - 21, - 9, - 21, - 10, - 21, - 11, - 21, - 12, - 21, - 13, - 21, - 14, - 21, - 15, - 21, - 16, - 21, - 17, - 21, - 18, - 21, - 19, - 21, - 20, - 21, - 21, - 21, - 22, - 21, - 23, - 21, - 24, - 21, - 25, - 21, - 26, - 22, - 0, - 22, - 1, - 22, - 2, - 22, - 3, - 22, - 4, - 22, - 5, - 22, - 6, - 22, - 7, - 22, - 8, - 22, - 9, - 22, - 10, - 22, - 11, - 22, - 12, - 22, - 13, - 22, - 14, - 22, - 15, - 22, - 16, - 22, - 17, - 22, - 18, - 22, - 19, - 22, - 20, - 22, - 21, - 22, - 22, - 22, - 23, - 22, - 24, - 22, - 25, - 22, - 26, - 23, - 0, - 23, - 1, - 23, - 2, - 23, - 3, - 23, - 4, - 23, - 5, - 23, - 6, - 23, - 7, - 23, - 8, - 23, - 9, - 23, - 10, - 23, - 11, - 23, - 12, - 23, - 13, - 23, - 14, - 23, - 15, - 23, - 16, - 23, - 17, - 23, - 18, - 23, - 19, - 23, - 20, - 23, - 21, - 23, - 22, - 23, - 23, - 23, - 24, - 23, - 25, - 23, - 26, - 24, - 0, - 24, - 1, - 24, - 2, - 24, - 3, - 24, - 4, - 24, - 5, - 24, - 6, - 24, - 7, - 24, - 8, - 24, - 9, - 24, - 10, - 24, - 11, - 24, - 12, - 24, - 13, - 24, - 14, - 24, - 15, - 24, - 16, - 24, - 17, - 24, - 18, - 24, - 19, - 24, - 20, - 24, - 21, - 24, - 22, - 24, - 23, - 24, - 24, - 24, - 25, - 24, - 26, - 25, - 0, - 25, - 1, - 25, - 2, - 25, - 3, - 25, - 4, - 25, - 5, - 25, - 6, - 25, - 7, - 25, - 8, - 25, - 9, - 25, - 10, - 25, - 11, - 25, - 12, - 25, - 13, - 25, - 14, - 25, - 15, - 25, - 16, - 25, - 17, - 25, - 18, - 25, - 19, - 25, - 20, - 25, - 21, - 25, - 22, - 25, - 23, - 25, - 24, - 25, - 25, - 25, - 26, - 26, - 0, - 26, - 1, - 26, - 2, - 26, - 3, - 26, - 4, - 26, - 5, - 26, - 6, - 26, - 7, - 26, - 8, - 26, - 9, - 26, - 10, - 26, - 11, - 26, - 12, - 26, - 13, - 26, - 14, - 26, - 15, - 26, - 16, - 26, - 17, - 26, - 18, - 26, - 19, - 26, - 20, - 26, - 21, - 26, - 22, - 26, - 23, - 26, - 24, - 26, - 25, - 26, - 26, -}; - -const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2] = { - NULL, - c_aaiHuffDemod1, - c_aaiHuffDemod2, - c_aaiHuffDemod3, - c_aaiHuffDemod4, - c_aaiHuffDemod5, - c_aaiHuffDemod6, - c_aaiHuffDemod7, - c_aaiHuffDemod8, - c_aaiHuffDemod9, - c_aaiHuffDemod10, - c_aaiHuffDemod11, - c_aaiHuffDemod12, - c_aaiHuffDemod13, - c_aaiHuffDemod14, - c_aaiHuffDemod15, - c_aaiHuffDemod16, - c_aaiHuffDemod17, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; -#endif const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = { 0x40, @@ -19845,4 +12098,3 @@ const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48] = { -121, -114, }; -#endif diff --git a/lib_rend/ivas_lcld_rom_tables.h b/lib_isar/isar_rom_lcld_tables.h similarity index 87% rename from lib_rend/ivas_lcld_rom_tables.h rename to lib_isar/isar_rom_lcld_tables.h index 8deb0aadf5e69fe570cc79af71396e3a7404b129..d59ad4a9dcca51ba43d34d30aa0be00a2d13328e 100644 --- a/lib_rend/ivas_lcld_rom_tables.h +++ b/lib_isar/isar_rom_lcld_tables.h @@ -30,16 +30,15 @@ *******************************************************************************************************/ -#ifndef _IVAS_TABLES_H_ -#define _IVAS_TABLES_H_ +#ifndef ISAR_ROM_LCLD_TABLES_H +#define ISAR_ROM_LCLD_TABLES_H #include #include "options.h" -#ifndef M_PI - -#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288f #endif #define LCLD_BLOCKS_PER_FRAME ( 16 ) @@ -47,10 +46,9 @@ #define LCLD_BANDS ( 60 ) #define LCLD_PRED_WIN_LEN ( 16 ) #define LCLD_MAX_NUM_PRED_SUBSETS ( 8 ) - -#define MAX_BANDS ( 23 ) -#define MAX_BANDS_48 ( 23 ) -#define DEF_BANDS_48 ( 22 ) +#define MAX_BANDS ( 23 ) +#define MAX_BANDS_48 ( 23 ) +#define DEF_BANDS_48 ( 22 ) #define ENV_MIN ( -64 ) #define ENV_MAX ( 64 ) @@ -93,10 +91,10 @@ #define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) -//#define USE_DEMOD_TABLES - #define HUFF_DEC_TABLE_SIZE ( 16 ) +extern const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48]; +extern const int32_t c_aiBandIdPerLcldBand[LCLD_BANDS]; extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; @@ -126,6 +124,11 @@ extern const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48]; #define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) #define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) + +/*----------------------------------------------------------------------* + * ISAR binaural rendering LCLD ROM tables + *-----------------------------------------------------------------------*/ + extern const uint16_t c_aauiLCLDHuffEnc1[16][2]; extern const uint16_t c_aauiLCLDHuffEnc2[16][2]; extern const uint16_t c_aauiLCLDHuffEnc3[25][2]; @@ -190,30 +193,7 @@ extern const uint16_t c_aauiLCLDHuffEnc62[153][2]; extern const uint16_t c_aauiLCLDHuffEnc63[181][2]; extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2]; extern const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE]; - -#ifdef USE_DEMOD_TABLES -extern const int32_t c_aaiHuffDemod1[16][2]; -extern const int32_t c_aaiHuffDemod2[16][2]; -extern const int32_t c_aaiHuffDemod3[25][2]; -extern const int32_t c_aaiHuffDemod4[36][2]; -extern const int32_t c_aaiHuffDemod5[36][2]; -extern const int32_t c_aaiHuffDemod6[49][2]; -extern const int32_t c_aaiHuffDemod7[64][2]; -extern const int32_t c_aaiHuffDemod8[81][2]; -extern const int32_t c_aaiHuffDemod9[100][2]; -extern const int32_t c_aaiHuffDemod10[169][2]; -extern const int32_t c_aaiHuffDemod11[196][2]; -extern const int32_t c_aaiHuffDemod12[289][2]; -extern const int32_t c_aaiHuffDemod13[324][2]; -extern const int32_t c_aaiHuffDemod14[400][2]; -extern const int32_t c_aaiHuffDemod15[576][2]; -extern const int32_t c_aaiHuffDemod16[729][2]; -extern const int32_t c_aaiHuffDemod17[729][2]; -extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2]; -#endif - extern const uint32_t c_aaiRMSEnvHuffEnc[64][2]; extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE]; - -#endif /* _TABLES_H_ */ +#endif /* ISAR_ROM_LCLD_TABLES_H_ */ diff --git a/lib_isar/isar_rom_post_rend.c b/lib_isar/isar_rom_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..aa88949601883ebe39a0b6c8b85181ba4a4547a2 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.c @@ -0,0 +1,179 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "isar_cnst.h" +#include "wmc_auto.h" + +/* clang-format off */ + + +/*----------------------------------------------------------------------* + * ISAR binaural split post-rendering ROM tables + *-----------------------------------------------------------------------*/ + +/* rotations in this array are relative to ref rotation */ +const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60 +}; + +const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + {0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12}, + {6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61}, + {12,7,125},{13,8,254},{14,8,255} +}; + +const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] = +{ + {-31,11,2040}, + {-30,11,2041}, + {-29,11,2042}, + {-28,11,2043}, + {-27,10,1012}, + {-26,10,1013}, + {-25,10,1014}, + {-24,10,1015}, + {-23,9,498}, + {-22,9,499}, + {-21,9,500}, + {-20,9,501}, + {-19,8,242}, + {-18,8,243}, + {-17,8,244}, + {-16,8,245}, + {-15,7,112}, + {-14,7,113}, + {-13,7,114}, + {-12,7,115}, + {-11,6,48}, + {-10,6,49}, + {-9,6,50}, + {-8,6,51}, + {-7,5,16}, + {-6,5,17}, + {-5,5,18}, + {-4,5,19}, + {-3,4,2}, + {-2,4,3}, + {-1,4,4}, + {0,3,0}, + {1,4,5}, + {2,4,6}, + {3,4,7}, + {4,5,20}, + {5,5,21}, + {6,5,22}, + {7,5,23}, + {8,6,52}, + {9,6,53}, + {10,6,54}, + {11,6,55}, + {12,7,116}, + {13,7,117}, + {14,7,118}, + {15,7,119}, + {16,7,120}, + {17,8,246}, + {18,8,247}, + {19,8,248}, + {20,9,502}, + {21,9,503}, + {22,9,504}, + {23,9,505}, + {24,10,1016}, + {25,10,1017}, + {26,10,1018}, + {27,10,1019}, + {28,11,2044}, + {29,11,2045}, + {30,11,2046}, + {31,11,2047}, +}; + +const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] = +{ + {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, + {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, + {14,10,1022},{15,10,1023}, +}; + +const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] = +{ + {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, + {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, +{14,10,1022},{15,10,1023}, +}; + + +/* clang-format on */ diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..36e3b74675db092ecdb6440f962dd4e3bcf57797 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.h @@ -0,0 +1,67 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_ROM_POST_REND_H +#define ISAR_ROM_POST_REND_H + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "isar_cnst.h" + + +/*----------------------------------------------------------------------* + * ISAR binarual split post-rendering ROM tables + *-----------------------------------------------------------------------*/ + +extern const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; +extern const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; + +extern const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; + +extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; +extern const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; +extern const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; + +#endif diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c similarity index 77% rename from lib_rend/ivas_splitRend_lcld_dec.c rename to lib_isar/isar_splitRend_lcld_dec.c index 9493d076af79417888b4e7ec4daef90abe10b43e..3333c5c0f10a3d4645d3faf479f9220f4f3f0995 100644 --- a/lib_rend/ivas_splitRend_lcld_dec.c +++ b/lib_isar/isar_splitRend_lcld_dec.c @@ -32,8 +32,7 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot_rend.h" +#include "isar_prot.h" #include "ivas_prot.h" #include "prot.h" #ifdef DEBUGGING @@ -43,23 +42,23 @@ /*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDDecOpen() + * Function isar_splitBinLCLDDecOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinLCLDDecOpen( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, +ivas_error isar_splitBinLCLDDecOpen( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */ const int32_t iSampleRate, const int16_t iChannels, const int16_t iNumBlocks, const int16_t iNumIterations ) { int16_t n; - BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; ivas_error error; - if ( ( splitBinLCLDDec = (BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) + if ( ( splitBinLCLDDec = (ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } @@ -68,7 +67,7 @@ ivas_error ivas_splitBinLCLDDecOpen( splitBinLCLDDec->iChannels = iChannels; - if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks ) ) != IVAS_ERR_OK ) + if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -107,7 +106,7 @@ ivas_error ivas_splitBinLCLDDecOpen( fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); #endif - if ( ( error = ivas_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC ) ) != IVAS_ERR_OK ) + if ( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK ) { return error; } @@ -121,13 +120,14 @@ ivas_error ivas_splitBinLCLDDecOpen( /*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDDecClose() + * Function isar_splitBinLCLDDecClose() * * *------------------------------------------------------------------------*/ -void ivas_splitBinLCLDDecClose( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) +void isar_splitBinLCLDDecClose( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec /* o : ISAR LCLD decoder handle */ +) { int16_t n; @@ -152,7 +152,7 @@ void ivas_splitBinLCLDDecClose( fclose( ( *hSplitBinLCLDDec )->cldfbOut ); } #endif - ivas_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); + isar_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); free( *hSplitBinLCLDDec ); *hSplitBinLCLDDec = NULL; @@ -163,21 +163,22 @@ void ivas_splitBinLCLDDecClose( /*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDDecProcess() + * Function isar_splitBinLCLDDecProcess() * * *------------------------------------------------------------------------*/ -void ivas_splitBinLCLDDecProcess( - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t bfi ) +void isar_splitBinLCLDDecProcess( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */ + const int16_t bfi /* i : BFI flag */ +) { int16_t k, n; int16_t itr; - push_wmops( "ivas_splitBinLCLDDecProcess" ); + push_wmops( "isar_splitBinLCLDDecProcess" ); assert( hSplitBinLCLDDec != NULL ); assert( Cldfb_Out_Real != NULL ); @@ -224,24 +225,34 @@ void ivas_splitBinLCLDDecProcess( } } #endif - if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) + if ( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) ) + { + /* continue concealing */ + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, + hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); + } + if ( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) ) { /* cross-fade recovered frame into good frame */ - ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + isar_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, + hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ), GetDecodingFailedPrevStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); } } } else { + /* set states in decoder */ + SetDecodingUnresolved( hSplitBinLCLDDec->psLCLDDecoder ); + /* do PLC for lost split renderer frame */ - ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, + hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); } /* save PLC state */ - ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); pop_wmops(); return; } -#endif diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c similarity index 90% rename from lib_rend/ivas_splitRend_lcld_enc.c rename to lib_isar/isar_splitRend_lcld_enc.c index 6903989dd158a5b880c30fdd8300e3fa319b2feb..1dda8f288a6506cef86878453ad94678f32c3ace 100644 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ b/lib_isar/isar_splitRend_lcld_enc.c @@ -32,8 +32,7 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot_rend.h" +#include "isar_prot.h" #include "ivas_prot.h" #ifdef DEBUGGING #include "debug.h" @@ -42,23 +41,23 @@ /*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDEncOpen() + * Function isar_splitBinLCLDEncOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinLCLDEncOpen( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, +ivas_error isar_splitBinLCLDEncOpen( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, /* o : ISAR LCLD handle */ const int32_t iSampleRate, const int16_t iChannels, const int32_t iDataRate, const int16_t iNumBlocks, const int16_t iNumIterations ) { - BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; ivas_error error; - if ( ( splitBinLCLDEnc = (BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) + if ( ( splitBinLCLDEnc = (ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } @@ -66,7 +65,7 @@ ivas_error ivas_splitBinLCLDEncOpen( splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/ splitBinLCLDEnc->iChannels = iChannels; - if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks ) ) != IVAS_ERR_OK ) + if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -115,13 +114,14 @@ ivas_error ivas_splitBinLCLDEncOpen( /*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDEncClose() + * Function isar_splitBinLCLDEncClose() * * *------------------------------------------------------------------------*/ -void ivas_splitBinLCLDEncClose( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) +void isar_splitBinLCLDEncClose( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc /* i/o: ISAR LCLD handle */ +) { if ( ( *hSplitBinLCLDEnc ) != NULL ) { @@ -151,20 +151,21 @@ void ivas_splitBinLCLDEncClose( /*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDEncProcess() + * Function isar_splitBinLCLDEncProcess() * * *------------------------------------------------------------------------*/ -void ivas_splitBinLCLDEncProcess( - BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, +void isar_splitBinLCLDEncProcess( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, /* i/o: ISAR LCLD encoder handle */ float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int32_t available_bits, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */ +) { int32_t iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local; - push_wmops( "ivas_splitBinLCLDEncProcess" ); + push_wmops( "isar_splitBinLCLDEncProcess" ); assert( hSplitBinLCLDEnc != NULL ); assert( Cldfb_In_Real != NULL ); @@ -239,4 +240,3 @@ void ivas_splitBinLCLDEncProcess( return; } -#endif diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_isar/isar_splitRendererPLC.c similarity index 85% rename from lib_rend/ivas_splitRendererPLC.c rename to lib_isar/isar_splitRendererPLC.c index 299430f28ee1191c44152cf4e49f645d6ff447f4..17e690d6e10f0a7edb3153e9cc21d3bc54a90f87 100644 --- a/lib_rend/ivas_splitRendererPLC.c +++ b/lib_isar/isar_splitRendererPLC.c @@ -32,12 +32,11 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "ivas_prot.h" #include "prot.h" #include "ivas_cnst.h" -#include "ivas_prot_rend.h" +#include "isar_prot.h" #ifdef DEBUGGING #include "debug.h" #endif @@ -48,8 +47,6 @@ * Local constants *------------------------------------------------------------------------*/ -#define DO_PERTURB 1 -#define PH_PERT_ONLY 1 #define START_VAL_AVG_LEN 2 #define SR_PLC_FADE_START 10 /* start fading at this number of bad frames in row */ #define SR_PLC_MUTE 30 /* Total mute at this number of bad frames in row */ @@ -68,13 +65,9 @@ static void adaptive_polar_ext_plc( const float *prev_real, const float *prev_imag, float *rec_real, - float *rec_imag -#if CLDFB_PLC_XF > 0 - , + float *rec_imag, float xf_alp[CLDFB_PLC_XF], - float xf_bet[CLDFB_PLC_XF] -#endif - , + float xf_bet[CLDFB_PLC_XF], const int16_t iNumCols ) { float uth[CLDFB_NO_COL_MAX], uthu[CLDFB_NO_COL_MAX], urh[CLDFB_NO_COL_MAX]; @@ -170,7 +163,6 @@ static void adaptive_polar_ext_plc( fac_real = min( 1, drho ) * fac_ph_real; fac_imag = min( 1, drho ) * fac_ph_imag; -#if START_VAL_AVG_LEN > 1 /* Calculate start value for evolution from last samples of previous frame */ fac_powj_real = fac_real; fac_powj_imag = fac_imag; @@ -186,28 +178,16 @@ static void adaptive_polar_ext_plc( } start_real *= 1.0f / START_VAL_AVG_LEN; start_imag *= 1.0f / START_VAL_AVG_LEN; -#else - /* take last sample of previous frame as start value */ - start_real = prev_real[iNumCols - 1]; - start_imag = prev_imag[iNumCols - 1]; -#endif -#if DO_PERTURB != 0 /* make evolution less static: apply per samples differences as in preceding frame */ rat_real = ( prev_real[1] * prev_real[0] + prev_imag[1] * prev_imag[0] ); rat_imag = ( -prev_real[1] * prev_imag[0] + prev_imag[1] * prev_real[0] ); -#if PH_PERT_ONLY != 0 + /* only phase perturbation */ abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); rat_real *= abs2inv; rat_imag *= abs2inv; -#else - /* phase and magnitude perturbation */ - abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) ); - rat_real *= abs2inv; - rat_imag *= abs2inv; -#endif /* apply complex evolution for first substitution sample */ rec_real[0] = rat_real * start_real - rat_imag * start_imag; @@ -217,14 +197,11 @@ static void adaptive_polar_ext_plc( /* make evolution less static: apply per samples differences as in preceding frame */ rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] ); -#if PH_PERT_ONLY != 0 + /* only phase perturbation */ abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); -#else - /* phase and magnitude perturbation */ - abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); -#endif + rat_real *= abs2inv; rat_imag *= abs2inv; /* apply complex evolution for further substitution samples */ @@ -237,28 +214,17 @@ static void adaptive_polar_ext_plc( { rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] ); -#if PH_PERT_ONLY != 0 + abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); -#else - abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); -#endif + rat_real *= abs2inv; rat_imag *= abs2inv; rec_real[j + iNumCols - 2] = rat_real * rec_real[j + iNumCols - 3] - rat_imag * rec_imag[j + iNumCols - 3]; rec_imag[j + iNumCols - 2] = rat_imag * rec_real[j + iNumCols - 3] + rat_real * rec_imag[j + iNumCols - 3]; } -#else - rec_real[0] = fac_real * start_real - fac_imag * start_imag; - rec_imag[0] = fac_imag * start_real + fac_real * start_imag; - for ( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ ) - { - rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1]; - rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1]; - } -#endif -#if CLDFB_PLC_XF > 0 + /* apply crossfade */ for ( j = 0; j < CLDFB_PLC_XF; j++ ) { @@ -266,7 +232,6 @@ static void adaptive_polar_ext_plc( rec_imag[iNumCols + j] *= xf_alp[j]; xf_bet[j] = 1 - xf_alp[j]; } -#endif } else { @@ -314,7 +279,6 @@ static void adaptive_polar_ext_plc( fac_powj_real = fac_real; fac_powj_imag = fac_imag; abs_fac_powj = abs_fac; -#if CLDFB_PLC_XF > 0 for ( j = 0; j < CLDFB_PLC_XF; j++ ) { xf_bet[j] = 1 - abs_fac_powj; @@ -325,7 +289,6 @@ static void adaptive_polar_ext_plc( fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; fac_powj_real = temp; } -#endif } } else @@ -335,14 +298,12 @@ static void adaptive_polar_ext_plc( rec_real[j] = prev_real[j]; rec_imag[j] = prev_imag[j]; } -#if CLDFB_PLC_XF > 0 for ( j = 0; j < CLDFB_PLC_XF; j++ ) { xf_bet[j] = 1; rec_real[j + iNumCols] = 0; rec_imag[j + iNumCols] = 0; } -#endif } return; @@ -350,25 +311,27 @@ static void adaptive_polar_ext_plc( /*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLCOpen() + * Function isar_splitBinRendPLCOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinRendPLCOpen( - SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, /* i/o: ISAR PLC handle */ + const int16_t iNumSubSets ) { ivas_error error; - SPLIT_REND_PLC_HANDLE hSplitRendPLC; + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; error = IVAS_ERR_OK; - if ( ( hSplitRendPLC = (SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL ) + if ( ( hSplitRendPLC = (ISAR_SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) ); } hSplitRendPLC->prev_bfi = 0; hSplitRendPLC->bf_count = 0; + hSplitRendPLC->iNumSubSets = iNumSubSets; set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); *phSplitRendPLC = hSplitRendPLC; @@ -378,13 +341,14 @@ ivas_error ivas_splitBinRendPLCOpen( /*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLCClose() + * Function isar_splitBinRendPLCClose() * * *------------------------------------------------------------------------*/ -void ivas_splitBinRendPLCClose( - SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +void isar_splitBinRendPLCClose( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC /* i/o: ISAR PLC handle */ +) { if ( ( *phSplitRendPLC ) != NULL ) { @@ -397,13 +361,13 @@ void ivas_splitBinRendPLCClose( /*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLCsaveState() + * Function isar_splitBinRendPLCsaveState() * * *------------------------------------------------------------------------*/ -void ivas_splitBinRendPLCsaveState( - SPLIT_REND_PLC_HANDLE hSplitRendPLC, +void isar_splitBinRendPLCsaveState( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs, @@ -427,18 +391,20 @@ void ivas_splitBinRendPLCsaveState( /*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLC_xf() + * Function isar_splitBinRendPLC_xf() * * Cross-fade of preceding bad frame into good frame *------------------------------------------------------------------------*/ -void ivas_splitBinRendPLC_xf( - SPLIT_REND_PLC_HANDLE hSplitRendPLC, +void isar_splitBinRendPLC_xf( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs, const int16_t iNumBlocks, - const int16_t iNumIterations ) + const int16_t iNumIterations, + int32_t **ppiDecodingFailed, + int32_t **ppiDecodingFailedPrev ) { int16_t n, i, k; @@ -454,13 +420,15 @@ void ivas_splitBinRendPLC_xf( { for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { -#if CLDFB_PLC_XF > 0 - for ( k = 0; k < CLDFB_PLC_XF; k++ ) + int16_t iSubSet = i % hSplitRendPLC->iNumSubSets; + if ( ppiDecodingFailedPrev[n][iSubSet] == 1 && ppiDecodingFailed[n][iSubSet] == 0 ) { - Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + ( iNumBlocks * iNumIterations )][i]; - Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + ( iNumBlocks * iNumIterations )][i]; + for ( k = 0; k < CLDFB_PLC_XF; k++ ) + { + Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + ( iNumBlocks * iNumIterations )][i]; + Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + ( iNumBlocks * iNumIterations )][i]; + } } -#endif } } @@ -469,25 +437,24 @@ void ivas_splitBinRendPLC_xf( /*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLC() + * Function isar_splitBinRendPLC() * * Conceal bad frame *------------------------------------------------------------------------*/ -void ivas_splitBinRendPLC( - SPLIT_REND_PLC_HANDLE hSplitRendPLC, +void isar_splitBinRendPLC( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t num_chs, const int16_t iNumBlocks, - const int16_t iNumIterations ) + const int16_t iNumIterations, + int32_t **ppiDecodingFailed ) { int32_t i, n, k; float fade_fac; float prev_real[CLDFB_NO_COL_MAX], prev_imag[CLDFB_NO_COL_MAX], rec_real[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; -#if CLDFB_PLC_XF > 0 float xf_alp[CLDFB_PLC_XF]; -#endif int16_t iNumCols, fade_start_cntr, mute_cntr, fade_val; iNumCols = iNumBlocks * iNumIterations; @@ -495,51 +462,46 @@ void ivas_splitBinRendPLC( /* Indicate that next transition will be from a bad frame */ hSplitRendPLC->prev_bfi = 1; - -#if CLDFB_PLC_XF > 0 for ( i = 0; i < CLDFB_PLC_XF; i++ ) { xf_alp[i] = 1.0f - ( i + 1.0f ) / ( CLDFB_PLC_XF + 1.0f ); } -#endif for ( n = 0; n < num_chs; n++ ) { for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { + int32_t iSubSet = i % hSplitRendPLC->iNumSubSets; for ( k = 0; k < iNumCols; k++ ) { prev_real[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i]; prev_imag[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i]; } - adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag -#if CLDFB_PLC_XF > 0 - , - xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i] -#endif - , + adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag, + xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i], iNumCols ); for ( k = 0; k < iNumCols; k++ ) { - Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; - Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; + + if ( ppiDecodingFailed[n][iSubSet] == 1 ) + { /* only then copy to output */ + Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; + Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k]; + } } -#if CLDFB_PLC_XF > 0 for ( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ ) { hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; } -#endif } } - /* Check bf counter */ fade_start_cntr = SR_PLC_FADE_START * CLDFB_NO_COL_MAX / iNumCols; mute_cntr = SR_PLC_MUTE * CLDFB_NO_COL_MAX / iNumCols; @@ -576,5 +538,3 @@ void ivas_splitBinRendPLC( return; } - -#endif diff --git a/lib_rend/ivas_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c similarity index 81% rename from lib_rend/ivas_splitRendererPost.c rename to lib_isar/isar_splitRendererPost.c index 002229d8b8e60b584d498f59b4f0c7ff99808134..27fd683f0824a0430a5fa7ed040043e6500b2186 100644 --- a/lib_rend/ivas_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -32,37 +32,44 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG #include #endif #include "ivas_prot.h" #include "prot.h" -#include "ivas_rom_dec.h" -#include "ivas_prot_rend.h" +#include "isar_rom_post_rend.h" +#include "isar_prot.h" #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" +/*---------------------------------------------------------------------* + * Local function declarations + *---------------------------------------------------------------------*/ + +static void isar_SplitRenderer_PostRenderer( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_RealBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], const IVAS_QUATERNION Quaternion_act ); + + /*------------------------------------------------------------------------- - * ivas_splitBinPostRendOpen() + * isar_splitBinPostRendOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinPostRendOpen( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs ) +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const int32_t output_Fs /* i : output sampling rate */ +) { - BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; ivas_error error; int16_t ch; - if ( ( hBinRend = (BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_POST_REND ) ) ) == NULL ) + if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_POST_REND ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split post renderer Module \n" ) ); } @@ -109,7 +116,7 @@ ivas_error ivas_splitBinPostRendOpen( hBinRend->cf_flag = 0; set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); - ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); *hBinHrSplitPostRend = hBinRend; return IVAS_ERR_OK; @@ -117,13 +124,14 @@ ivas_error ivas_splitBinPostRendOpen( /*------------------------------------------------------------------------- - * ivas_splitBinPostRendClose() + * isar_splitBinPostRendClose() * * *------------------------------------------------------------------------*/ -void ivas_splitBinPostRendClose( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) +void isar_splitBinPostRendClose( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend /* i/o: binaural post-renderer handle */ +) { int16_t ch; @@ -165,14 +173,14 @@ void ivas_splitBinPostRendClose( /*-----------------------------------------------------------------------------------------* - * Function ivas_split_rend_huffman_decode_opt() + * Function isar_split_rend_huffman_decode_opt() * * *-----------------------------------------------------------------------------------------*/ -static int16_t ivas_split_rend_huffman_decode_opt( - ivas_split_rend_huffman_cfg_t *huff_cfg, - IVAS_SPLIT_REND_BITS_HANDLE pBits, +static int16_t isar_split_rend_huffman_decode_opt( + isar_split_rend_huffman_cfg_t *huff_cfg, + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ const int16_t *idx_trav_list ) { int32_t i, ind, code, num_bits, code_b, num_bits_read; @@ -191,7 +199,7 @@ static int16_t ivas_split_rend_huffman_decode_opt( code = code << num_bits_read; if ( num_bits_read > 0 ) { - code |= ivas_split_rend_bitstream_read_int32( pBits, num_bits_read ); + code |= ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read ); } if ( code == code_b ) @@ -210,16 +218,17 @@ static int16_t ivas_split_rend_huffman_decode_opt( return (int16_t) ind; } + /*-----------------------------------------------------------------------------------------* - * Function ivas_split_rend_unquant_md() + * Function isar_split_rend_unquant_md() * * *-----------------------------------------------------------------------------------------*/ -static void ivas_split_rend_unquant_md( - BIN_HR_SPLIT_REND_MD_HANDLE hMd, - IVAS_SPLIT_REND_POSE_TYPE pose_type, - int16_t real_only, +static void isar_split_rend_unquant_md( + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + ISAR_SPLIT_REND_POSE_TYPE pose_type, + const int16_t real_only, float fix_pos_rot_mat[][BINAURAL_CHANNELS], const float pred_quant_step ) { @@ -231,17 +240,17 @@ static void ivas_split_rend_unquant_md( float quantstep; quantstep = pred_quant_step; - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + if ( real_only ) { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; - hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + ( ( ch1 == ch2 ) ? 1.0f : 0.0f ); + } } - } - if ( real_only ) - { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) @@ -252,6 +261,15 @@ static void ivas_split_rend_unquant_md( } else { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) @@ -263,18 +281,18 @@ static void ivas_split_rend_unquant_md( } else if ( pose_type == COM_GAIN_ONLY ) { - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL ); hMd->gd_idx += gd_idx_min; - hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; + hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP; } else if ( pose_type == LR_GAIN_ONLY ) { - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL ); hMd->gd_idx += gd_idx_min; - hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP; hMd->gd2_idx += gd_idx_min; - hMd->gd2 = hMd->gd2_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + hMd->gd2 = hMd->gd2_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP; } else { @@ -286,15 +304,15 @@ static void ivas_split_rend_unquant_md( /*-----------------------------------------------------------------------------------------* - * Function ivas_splitBinPostRendMdBase2Dec() + * Function isar_splitBinPostRendMdBase2Dec() * * *-----------------------------------------------------------------------------------------*/ -static void ivas_splitBinPostRendMdBase2Dec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_splitBinPostRendMdBase2Dec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -309,12 +327,12 @@ static void ivas_splitBinPostRendMdBase2Dec( int16_t min_pred_roll_idx, pred_roll_code_len; int16_t pred_cb_idx; int16_t code; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) { pred_cb_idx = 1; } @@ -337,34 +355,42 @@ static void ivas_splitBinPostRendMdBase2Dec( { if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) { - for ( b = 0; b < pred_real_bands_yaw; b++ ) + for ( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; } } - } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; } } } + + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_idx; + } + hMd->pred_mat_re_idx[0][1] = 0; + hMd->pred_mat_re_idx[1][0] = 0; + } for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, gd_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, gd_code_len ); hMd->gd_idx = code + min_gd_idx; } } @@ -373,38 +399,46 @@ static void ivas_splitBinPostRendMdBase2Dec( for ( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ); hMd->gd_idx = code + min_p_gd_idx; - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, p_gd_code_len ); hMd->gd2_idx = code + min_p_gd_idx; } } else { - for ( b = 0; b < pred_real_bands_roll; b++ ) + for ( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx; } } - } - for ( b = 0; b < pred_imag_bands_roll; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len ); + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx; } } } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); + hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_roll_idx; + } + hMd->pred_mat_re_idx[0][1] = 0; + hMd->pred_mat_re_idx[1][0] = 0; + } } } } @@ -414,15 +448,15 @@ static void ivas_splitBinPostRendMdBase2Dec( /*-----------------------------------------------------------------------------------------* - * Function ivas_splitBinPostRendMdHuffDec() + * Function isar_splitBinPostRendMdHuffDec() * * *-----------------------------------------------------------------------------------------*/ -static void ivas_splitBinPostRendMdHuffDec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_splitBinPostRendMdHuffDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -437,12 +471,12 @@ static void ivas_splitBinPostRendMdHuffDec( int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; int16_t min_pred_idx, max_pred_idx; int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) { pred_cb_idx = 1; } @@ -454,7 +488,7 @@ static void ivas_splitBinPostRendMdHuffDec( max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3]; min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0]; - max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; + max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) { @@ -462,37 +496,41 @@ static void ivas_splitBinPostRendMdHuffDec( { if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) { - for ( b = 0; b < pred_real_bands_yaw; b++ ) + for ( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); - // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); } } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); - } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); - // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); } } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + } + sym_adj_idx[1][0] = 0; + sym_adj_idx[0][1] = 0; + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_idx, max_pred_idx ); } for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav ); - // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); + hMd->gd_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav ); } } else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) @@ -500,15 +538,14 @@ static void ivas_splitBinPostRendMdHuffDec( for ( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); - // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); + hMd->gd_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); - hMd->gd2_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + hMd->gd2_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); } } else { - for ( b = 0; b < pred_real_bands_roll; b++ ) + for ( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; @@ -516,24 +553,31 @@ static void ivas_splitBinPostRendMdHuffDec( { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); - // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); } } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); - } - for ( b = 0; b < pred_imag_bands_roll; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); - // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred_roll, pBits ); + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); } } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + } + sym_adj_idx[1][0] = 0; + sym_adj_idx[0][1] = 0; + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); } } } @@ -544,15 +588,15 @@ static void ivas_splitBinPostRendMdHuffDec( /*-----------------------------------------------------------------------------------------* - * Function ivas_splitBinPostRendMdDec() + * Function isar_splitBinPostRendMdDec() * * *-----------------------------------------------------------------------------------------*/ -void ivas_splitBinPostRendMdDec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +void isar_splitBinPostRendMdDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend @@ -560,28 +604,40 @@ void ivas_splitBinPostRendMdDec( ) { int16_t pos_idx, b, sf_idx, num_subframes, ch1; - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t num_complex_bands, num_quant_strats; + int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t num_quant_strats; int32_t quant_strat_bits, is_huff_coding, quant_strat; - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG int16_t ch1, ch2; #endif - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; - IVAS_SPLIT_REND_ROT_AXIS rot_axis; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + int16_t ro_md_flag, num_bits, axis_code; hBinHrSplitPostRend->low_Res = 1; - split_rend_config.dof = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_DOF_BITS ); - split_rend_config.hq_mode = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HQ_MODE_BITS ); - rot_axis = (IVAS_SPLIT_REND_ROT_AXIS) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_ROT_AXIS_BITS ); + split_rend_config.dof = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_DOF_BITS ); + split_rend_config.hq_mode = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HQ_MODE_BITS ); + + num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof ); + if ( num_bits > 0 ) + { + axis_code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, (int32_t) num_bits ); + } + else + { + axis_code = 0; + } + rot_axis = isar_renderSplitGetRot_axisFromCode( split_rend_config.dof, axis_code ); + ro_md_flag = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_RO_FLAG_BITS ); - ivas_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); + isar_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); set_pose_types( hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); @@ -593,20 +649,20 @@ void ivas_splitBinPostRendMdDec( hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; - angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); angle -= 180; hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = (float) angle; - angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); angle -= 180; hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = (float) angle; - angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); angle -= 180; hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle; } - ivas_split_rend_get_quant_params( + isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, @@ -617,16 +673,16 @@ void ivas_splitBinPostRendMdDec( bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, - &num_quant_strats, - &num_complex_bands ); + ro_md_flag, + &num_quant_strats ); quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); - is_huff_coding = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - quant_strat = ivas_split_rend_bitstream_read_int32( pBits, quant_strat_bits ); + is_huff_coding = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + quant_strat = ISAR_SPLIT_REND_BITStream_read_int32( pBits, quant_strat_bits ); if ( is_huff_coding == 0 ) { - ivas_splitBinPostRendMdBase2Dec( + isar_splitBinPostRendMdBase2Dec( pBits, hBinHrSplitPostRend, pMultiBinPoseData, num_subframes, @@ -640,7 +696,7 @@ void ivas_splitBinPostRendMdDec( } else { - ivas_splitBinPostRendMdHuffDec( + isar_splitBinPostRendMdHuffDec( pBits, hBinHrSplitPostRend, pMultiBinPoseData, num_subframes, @@ -765,12 +821,12 @@ void ivas_splitBinPostRendMdDec( for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); + isar_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); } for ( ; b < pred_real_bands_yaw[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); + isar_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); } for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { @@ -785,7 +841,7 @@ void ivas_splitBinPostRendMdDec( for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); + isar_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); } for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { @@ -798,7 +854,7 @@ void ivas_splitBinPostRendMdDec( for ( b = 0; b < bands_pitch[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); + isar_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); } for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { @@ -812,12 +868,12 @@ void ivas_splitBinPostRendMdDec( for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP ); + isar_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ); } for ( ; b < pred_real_bands_roll[quant_strat]; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP ); + isar_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ); } for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { @@ -950,6 +1006,7 @@ static void wrap_around_angle( { ( *a ) = ( *a ) + 360; } + return; } @@ -970,6 +1027,7 @@ static void wrap_around_ypr( wrap_around_angle( &Quaternions->y ); wrap_around_angle( &Quaternions->z ); } + return; } @@ -1062,7 +1120,7 @@ static void get_nearest_pose_ind( *-----------------------------------------------------------------------------------------*/ static void get_interpolation_vars( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const IVAS_QUATERNION *Quaternions_ref, const IVAS_QUATERNION *Quaternions_act, int16_t interp_yaw_pose_idx[2], @@ -1136,7 +1194,7 @@ static void get_interpolation_vars( *-----------------------------------------------------------------------------------------*/ static void interpolate_pred_matrix( - BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], const int16_t sf_idx, const int16_t band_idx, const int16_t ind[2], @@ -1146,7 +1204,7 @@ static void interpolate_pred_matrix( { int16_t ch_idx1, ch_idx2; float diff; - BIN_HR_SPLIT_REND_MD *pRot_md; + ISAR_BIN_HR_SPLIT_REND_MD *pRot_md; float mix_mat_re1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float mix_mat_im1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float mix_mat_re2[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -1214,7 +1272,7 @@ static void interpolate_pred_matrix( *-----------------------------------------------------------------------------------------*/ static void interpolate_rend_md( - BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + ISAR_BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], float mix_mat_re[][BINAURAL_CHANNELS], float mix_mat_im[][BINAURAL_CHANNELS], float *gd_int, @@ -1317,7 +1375,7 @@ static void interpolate_rend_md( { interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, mix_mat_im3 ); - ivas_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 ); + isar_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 ); for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { @@ -1334,25 +1392,25 @@ static void interpolate_rend_md( /*-----------------------------------------------------------------------------------------* - * Function ivas_SplitRenderer_PostRenderer() + * Function isar_SplitRenderer_PostRenderer() * * *-----------------------------------------------------------------------------------------*/ -void ivas_SplitRenderer_PostRenderer( - BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_SplitRenderer_PostRenderer( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ const IVAS_QUATERNION Quaternion_act ) { int16_t pos_idx, b, brange[2], ch_idx1; - int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md; + int16_t num_md_bands, slot_idx, b2, num_slots, sf_idx_md; float pred_out_re[BINAURAL_CHANNELS], pred_out_im[BINAURAL_CHANNELS], tmp_re, tmp_im, gd_int; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; + ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; #else - BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS]; + ISAR_BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS]; #endif int16_t interp_yaw_pose_idx[2], interp_pitch_pose_idx[2], interp_roll_pose_idx[2]; float interp_yaw_fact, interp_pitch_fact, interp_roll_fact; @@ -1365,11 +1423,11 @@ void ivas_SplitRenderer_PostRenderer( float fade; float *pMix_mat_re_prev[BINAURAL_CHANNELS]; float *pMix_mat_im_prev[BINAURAL_CHANNELS]; - const int16_t *pBand_grouping = ivas_split_rend_band_grouping; + const int16_t *pBand_grouping = isar_split_rend_band_grouping; num_md_bands = MAX_SPLIT_REND_MD_BANDS; - push_wmops( "ivas_SplitRenderer_PostRenderer" ); + push_wmops( "isar_SplitRenderer_PostRenderer" ); num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG @@ -1403,7 +1461,6 @@ void ivas_SplitRenderer_PostRenderer( } } - #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) { @@ -1440,9 +1497,6 @@ void ivas_SplitRenderer_PostRenderer( } } -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) #else pos_idx = 0; @@ -1450,7 +1504,6 @@ void ivas_SplitRenderer_PostRenderer( { for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) { - index_slot = slot_idx; /* TODO: can be cleaned up */ fade = ( (float) slot_idx + 1.0f ) / MAX_PARAM_SPATIAL_SUBFRAMES; fade = min( fade, 1.0f ); for ( b = 0; b < num_md_bands; b++ ) @@ -1487,8 +1540,8 @@ void ivas_SplitRenderer_PostRenderer( for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { /* Apply prediction matrix */ - IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][index_slot][b2], - Cldfb_ImagBuffer_Ref_Binaural[0][index_slot][b2], + IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][slot_idx][b2], + Cldfb_ImagBuffer_Ref_Binaural[0][slot_idx][b2], mix_mat_re[0][ch_idx1], mix_mat_im[0][ch_idx1], tmp_re, @@ -1496,8 +1549,8 @@ void ivas_SplitRenderer_PostRenderer( pred_out_re[ch_idx1] = tmp_re; pred_out_im[ch_idx1] = tmp_im; - IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[1][index_slot][b2], - Cldfb_ImagBuffer_Ref_Binaural[1][index_slot][b2], + IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[1][slot_idx][b2], + Cldfb_ImagBuffer_Ref_Binaural[1][slot_idx][b2], mix_mat_re[1][ch_idx1], mix_mat_im[1][ch_idx1], tmp_re, @@ -1510,11 +1563,11 @@ void ivas_SplitRenderer_PostRenderer( for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_re[ch_idx1]; - Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; + Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][slot_idx][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][slot_idx][b2] = pred_out_im[ch_idx1]; #else - Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_re[ch_idx1]; - Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; + Cldfb_RealBuffer_Ref_Binaural[ch_idx1][slot_idx][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][slot_idx][b2] = pred_out_im[ch_idx1]; #endif } } @@ -1564,7 +1617,7 @@ void ivas_SplitRenderer_PostRenderer( tag[1] = '\0'; strcat( fname, tag ); strcat( fname, ".wav" ); - ivas_log_cldfb2wav_data( + isar_log_cldfb2wav_data( Cldfb_RealBuffer_Recons_Binaural[pos_idx], Cldfb_ImagBuffer_Recons_Binaural[pos_idx], hBinPostRenderer->cldfbSynReconsBinDec[pos_idx], @@ -1576,22 +1629,22 @@ void ivas_SplitRenderer_PostRenderer( fname ); } } -#endif +#endif pop_wmops(); return; } /*-----------------------------------------------------------------------------------------* - * Function ivas_rend_CldfbSplitPostRendProcessTdIn() + * Function isar_rend_CldfbSplitPostRendProcessTdIn() * * *-----------------------------------------------------------------------------------------*/ -static void ivas_rend_CldfbSplitPostRendProcessTdIn( - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_rend_CldfbSplitPostRendProcessTdIn( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const IVAS_QUATERNION QuaternionPost, float output[][L_FRAME48k] ) { @@ -1613,7 +1666,7 @@ static void ivas_rend_CldfbSplitPostRendProcessTdIn( } } - ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); /* Implement CLDFB synthesis */ for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) @@ -1635,14 +1688,14 @@ static void ivas_rend_CldfbSplitPostRendProcessTdIn( /*-----------------------------------------------------------------------------------------* - * Function ivas_rend_CldfbSplitPostRendProcess() + * Function isar_rend_CldfbSplitPostRendProcess() * * *-----------------------------------------------------------------------------------------*/ -void ivas_rend_CldfbSplitPostRendProcess( - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +void isar_rend_CldfbSplitPostRendProcess( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const IVAS_QUATERNION QuaternionPost, float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], @@ -1651,18 +1704,18 @@ void ivas_rend_CldfbSplitPostRendProcess( { int16_t ch_idx, slot_idx, num_cldfb_bands; - push_wmops( "ivas_rend_CldfbSplitPostRendProcess" ); + push_wmops( "isar_rend_CldfbSplitPostRendProcess" ); num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; if ( cldfb_in_flag == 0 ) { - ivas_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output ); + isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output ); pop_wmops(); return; } - ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); /* Implement CLDFB synthesis */ for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) @@ -1685,20 +1738,20 @@ void ivas_rend_CldfbSplitPostRendProcess( /*-----------------------------------------------------------------------------------------* - * Function ivas_init_split_post_rend_handles() + * Function isar_init_split_post_rend_handles() * * *-----------------------------------------------------------------------------------------*/ -void ivas_init_split_post_rend_handles( - SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer post-renderer handle */ +) { hSplitRendWrapper->hBinHrSplitPostRend = NULL; hSplitRendWrapper->hSplitBinLCLDDec = NULL; hSplitRendWrapper->hLc3plusDec = NULL; - ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); hSplitRendWrapper->first_good_frame_received = 0; return; } -#endif diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c similarity index 66% rename from lib_rend/ivas_splitRendererPre.c rename to lib_isar/isar_splitRendererPre.c index 25bc04dfb50dba53d411d4713ee69c5e90d3d960..4cd4855ecc63d46c08c3e1c94f76562f85b45eeb 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_isar/isar_splitRendererPre.c @@ -32,16 +32,15 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG #include #endif #include "ivas_prot.h" #include "prot.h" -#include "ivas_cnst.h" -#include "ivas_rom_dec.h" -#include "ivas_prot_rend.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" #ifdef DEBUGGING #include "debug.h" #endif @@ -50,6 +49,12 @@ #include "string.h" #endif +/*---------------------------------------------------------------------* + * Local function declarations + *---------------------------------------------------------------------*/ + +static void isar_SplitRenderer_GetRotMd( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t low_res, const int16_t ro_md_flag ); + /*------------------------------------------------------------------------- * Local functions @@ -57,7 +62,7 @@ * *------------------------------------------------------------------------*/ -static void ivas_calc_mat_det_2by2_complex( +static void isar_calc_mat_det_2by2_complex( float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float *det_re, @@ -74,14 +79,14 @@ static void ivas_calc_mat_det_2by2_complex( } -static int16_t ivas_is_mat_inv_2by2_complex( +static int16_t isar_is_mat_inv_2by2_complex( float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) { int16_t is_det_zero = 1; float det, det_re, det_im; - ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); det = ( ( det_re * det_re ) + ( det_im * det_im ) ); @@ -94,7 +99,7 @@ static int16_t ivas_is_mat_inv_2by2_complex( } -static void ivas_calc_mat_inv_2by2_complex( +static void isar_calc_mat_inv_2by2_complex( float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float out_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], @@ -103,7 +108,7 @@ static void ivas_calc_mat_inv_2by2_complex( float det_re, det_im; float re, im, det; - ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); det = ( det_re * det_re ) + ( det_im * det_im ); @@ -140,8 +145,8 @@ static void ComputePredMat( float cov_io_im[][BINAURAL_CHANNELS], float pred_mat_re[][BINAURAL_CHANNELS], float pred_mat_im[][BINAURAL_CHANNELS], - int16_t num_chs, - int16_t real_only ) + const int16_t num_chs, + const int16_t real_only ) { float cov_ii_local_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_ii_inv_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -178,10 +183,10 @@ static void ComputePredMat( cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f ); } - if ( ivas_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) + if ( isar_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) { - ivas_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im ); - ivas_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im ); + isar_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im ); + isar_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im ); } else { @@ -226,14 +231,14 @@ static void ComputePostPredCov( float pred_mat_re[][BINAURAL_CHANNELS], float pred_mat_im[][BINAURAL_CHANNELS], float postpred_cov_re[][BINAURAL_CHANNELS], - float postpred_cov_im[][BINAURAL_CHANNELS], - int16_t num_chs ) + const int16_t num_chs ) { int16_t i, j; float dmx_mat_conj_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float dmx_mat_conj_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float temp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float temp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; assert( num_chs == BINAURAL_CHANNELS ); for ( i = 0; i < num_chs; i++ ) @@ -247,21 +252,18 @@ static void ComputePostPredCov( temp_mat_im[i][j] = pred_mat_im[i][j]; } set_zero( postpred_cov_re[i], BINAURAL_CHANNELS ); - set_zero( postpred_cov_im[i], BINAURAL_CHANNELS ); } /* 2x2 mult */ - ivas_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im ); - ivas_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, postpred_cov_re, postpred_cov_im ); + isar_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im ); + isar_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, postpred_cov_re, postpred_cov_im ); for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { for ( j = 0; j < i; j++ ) { postpred_cov_re[i][j] = postpred_cov_re[j][i]; - postpred_cov_im[i][j] = -postpred_cov_im[j][i]; } - postpred_cov_im[i][i] = 0; } return; @@ -446,9 +448,9 @@ static float GetNormFact( } -static void ivas_split_rend_huffman_encode( - ivas_split_rend_huffman_cfg_t *huff_cfg, - int16_t in, +static void isar_split_rend_huffman_encode( + isar_split_rend_huffman_cfg_t *huff_cfg, + const int16_t in, int32_t *hcode, int32_t *hlen ) { @@ -465,16 +467,16 @@ static void ivas_split_rend_huffman_encode( } -static void ivas_split_rend_quant_md( - BIN_HR_SPLIT_REND_MD_HANDLE hMd, - IVAS_SPLIT_REND_POSE_TYPE pose_type, - int16_t real_only, +static void isar_split_rend_quant_md( + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + const ISAR_SPLIT_REND_POSE_TYPE pose_type, + const int16_t real_only, float fix_pos_rot_mat[][BINAURAL_CHANNELS], const float pred_1byquantstep ) { int16_t ch1, ch2; int16_t gd_idx_min; - float sign, quant_val; + float quant_val; if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) { @@ -483,25 +485,34 @@ static void ivas_split_rend_quant_md( onebyquantstep = pred_1byquantstep; if ( real_only == 1 ) { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1]; + } + + hMd->pred_mat_re[1][0] = 0.0f; + hMd->pred_mat_re[0][1] = 0.0f; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f; - IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] ); - hMd->pred_mat_re[ch1][ch2] *= sign; - hMd->pred_mat_im[ch1][ch2] = 0.0f; + quant_val = hMd->pred_mat_re[ch1][ch2] - ( ( ch1 == ch2 ) ? 1.0f : 0.0f ); + quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); } } } - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + else { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { - quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2]; - quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( quant_val, IVAS_SPLIT_REND_PRED_MIN_VAL ) ); - hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2]; + quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + } } } @@ -511,30 +522,29 @@ static void ivas_split_rend_quant_md( { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], IVAS_SPLIT_REND_PRED_MIN_VAL ) ); + quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], ISAR_SPLIT_REND_PRED_MIN_VAL ) ); hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); - // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; } } } } else if ( pose_type == COM_GAIN_ONLY ) { - quant_val = min( IVAS_SPLIT_REND_D_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); - hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * quant_val ); - hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; + quant_val = min( ISAR_SPLIT_REND_D_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_D_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * ISAR_SPLIT_REND_D_MIN_VAL ); + hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_D_1BYQ_STEP * quant_val ); + hMd->gd = hMd->gd_idx * ISAR_SPLIT_REND_D_Q_STEP; hMd->gd_idx = hMd->gd_idx - gd_idx_min; } else if ( pose_type == LR_GAIN_ONLY ) { - quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); - hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); + quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * ISAR_SPLIT_REND_PITCH_G_MIN_VAL ); + hMd->gd_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); hMd->gd_idx = hMd->gd_idx - gd_idx_min; - quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); - hMd->gd2_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); + quant_val = min( ISAR_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ); + hMd->gd2_idx = (int16_t) roundf( ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); hMd->gd2_idx = hMd->gd2_idx - gd_idx_min; } @@ -542,18 +552,42 @@ static void ivas_split_rend_quant_md( } +static void get_lr_gains( + float cov_in[][BINAURAL_CHANNELS], + float cov_out[][BINAURAL_CHANNELS], + float gains[BINAURAL_CHANNELS] ) +{ + int16_t i; + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gains[i] = cov_in[i][i]; + if ( gains[i] < EPSILON ) + { + gains[i] = 1.0f; + } + else + { + gains[i] = ( cov_out[i][i] ) / gains[i]; + gains[i] = sqrtf( gains[i] ); + } + } + + return; +} + + static void ComputeCoeffs( float cov_ii_re[][BINAURAL_CHANNELS], float cov_ii_im[][BINAURAL_CHANNELS], float cov_io_re[][BINAURAL_CHANNELS], float cov_io_im[][BINAURAL_CHANNELS], float cov_oo_re[][BINAURAL_CHANNELS], - BIN_HR_SPLIT_REND_MD_HANDLE hMd, - const IVAS_SPLIT_REND_POSE_TYPE pose_type, + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + const ISAR_SPLIT_REND_POSE_TYPE pose_type, const int16_t real_only ) { float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_ii_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_ii_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_io_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -566,19 +600,8 @@ static void ComputeCoeffs( { float gd_tmp[BINAURAL_CHANNELS]; - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - gd_tmp[i] = cov_ii_re[i][i]; - if ( gd_tmp[i] < EPSILON ) - { - gd_tmp[i] = 1.0f; - } - else - { - gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; - gd_tmp[i] = sqrtf( gd_tmp[i] ); - } - } + get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); + hMd->gd = gd_tmp[0]; hMd->gd2 = gd_tmp[1]; } @@ -588,26 +611,22 @@ static void ComputeCoeffs( { float gd_tmp[BINAURAL_CHANNELS]; + get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - gd_tmp[i] = cov_ii_re[i][i]; - if ( gd_tmp[i] < EPSILON ) - { - gd_tmp[i] = 1.0f; - } - else - { - gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; - gd_tmp[i] = sqrtf( gd_tmp[i] ); - } hMd->pred_mat_re[i][i] = gd_tmp[i]; + hMd->pred_mat_re2[i] = gd_tmp[i]; set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); } + hMd->pred_mat_re[1][0] = 0.0f; hMd->pred_mat_re[0][1] = 0.0f; } else { + get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 ); + cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); /* normalize the covariance */ @@ -625,8 +644,7 @@ static void ComputeCoeffs( ComputePredMat( cov_ii_norm_re, cov_ii_norm_im, cov_io_norm_re, cov_io_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, BINAURAL_CHANNELS, real_only ); - /*TODO : change this function to real only as thats what is needed*/ - ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, postpred_cov_im, BINAURAL_CHANNELS ); + ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, BINAURAL_CHANNELS ); /* normalize everything to +-1 range */ gd = 1.0f / ( PCM16_TO_FLT_FAC ); @@ -688,32 +706,32 @@ static void ComputeCoeffs( static void get_base2_bits( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t num_quant_strats, - const int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS] ) + const int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS] ) { int16_t pred_roll_bits; int16_t d_gain_bits, pitch_gain_bits, pose_idx, q; - int16_t pred_yaw_bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_yaw_bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; - IVAS_SPLIT_REND_POSE_TYPE pose_type; + ISAR_SPLIT_REND_POSE_TYPE pose_type; for ( q = 0; q < num_quant_strats; q++ ) { pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) ); } - pred_roll_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) ); + pred_roll_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) ); - d_gain_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_D_QUANT_PNTS ) ); + d_gain_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_D_QUANT_PNTS ) ); pitch_gain_bits = d_gain_bits; for ( q = 0; q < num_quant_strats; q++ ) @@ -728,7 +746,8 @@ static void get_base2_bits( pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; if ( pose_type == ANY_YAW ) { - base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS; + base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS; base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes; } @@ -739,7 +758,8 @@ static void get_base2_bits( } else { - base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS; + base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS; base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; } } @@ -749,9 +769,9 @@ static void get_base2_bits( } -static void ivas_SplitRenderer_code_md_base2( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_SplitRenderer_code_md_base2( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -760,18 +780,19 @@ static void ivas_SplitRenderer_code_md_base2( const int16_t bands_pitch, const int16_t pred_real_bands_roll, const int16_t pred_imag_bands_roll, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */ +) { int16_t pos_idx, b, ch1, ch2, sf_idx; int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses; int16_t min_pred_roll_idx, pred_roll_code_len; int16_t pred_cb_idx; int32_t code; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) { pred_cb_idx = 1; } @@ -797,7 +818,7 @@ static void ivas_SplitRenderer_code_md_base2( { if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) { - for ( b = 0; b < pred_real_bands_yaw; b++ ) + for ( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) @@ -805,28 +826,35 @@ static void ivas_SplitRenderer_code_md_base2( for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } - } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } } + + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } + for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; code = hMd->gd_idx - min_gd_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, gd_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, gd_code_len ); } } else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) @@ -835,15 +863,15 @@ static void ivas_SplitRenderer_code_md_base2( { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; code = hMd->gd_idx - min_p_gd_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); code = hMd->gd2_idx - min_p_gd_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); } } else { - for ( b = 0; b < pred_real_bands_roll; b++ ) + for ( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) @@ -851,23 +879,28 @@ static void ivas_SplitRenderer_code_md_base2( for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } - } - - for ( b = 0; b < pred_imag_bands_roll; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } } } } @@ -895,9 +928,9 @@ static void ivas_SplitRenderer_code_md_base2( } -static void ivas_SplitRenderer_code_md_huff( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_SplitRenderer_code_md_huff( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -906,19 +939,20 @@ static void ivas_SplitRenderer_code_md_huff( const int16_t bands_pitch, const int16_t pred_real_bands_roll, const int16_t pred_imag_bands_roll, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */ +) { int16_t pos_idx, b, ch1, ch2, sf_idx, num_poses; int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; int16_t min_pred_idx, max_pred_idx; int16_t min_pred_roll_idx, max_pred_roll_idx, pred_cb_idx; int32_t code, len; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + if ( pred_quant_pnts_yaw == ISAR_SPLIT_REND_PRED_63QUANT_PNTS ) { pred_cb_idx = 1; } @@ -930,7 +964,7 @@ static void ivas_SplitRenderer_code_md_huff( min_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[0]; max_pred_idx = (int16_t) pHuff_cfg->pred[pred_cb_idx].codebook[( pred_quant_pnts_yaw - 1 ) * 3]; min_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[0]; - max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; + max_pred_roll_idx = (int16_t) pHuff_cfg->pred_roll.codebook[( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; num_poses = pMultiBinPoseData->num_poses; @@ -940,39 +974,45 @@ static void ivas_SplitRenderer_code_md_huff( { if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) { - for ( b = 0; b < pred_real_bands_yaw; b++ ) + for ( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } - } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - - ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); - - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } + + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) @@ -980,41 +1020,49 @@ static void ivas_SplitRenderer_code_md_huff( for ( b = 0; b < bands_pitch; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); - ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } else { - for ( b = 0; b < pred_real_bands_roll; b++ ) + for ( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } - } - for ( b = 0; b < pred_imag_bands_roll; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch1], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } } } } @@ -1041,24 +1089,27 @@ static void ivas_SplitRenderer_code_md_huff( } -static void ivas_SplitRenderer_quant_code( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - const IVAS_QUATERNION headPosition, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int16_t low_res_pre_rend_rot, - const int32_t target_md_bits ) +static void isar_SplitRenderer_quant_code( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t ro_md_flag, /* i : real only metadata for yaw flag */ + const int32_t target_md_bits /* i : ISAR MD bitrate */ +) { - int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; + int16_t q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; + int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int32_t base2bits[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; + int16_t rot_axis_code, num_bits; if ( low_res_pre_rend_rot ) { @@ -1071,9 +1122,16 @@ static void ivas_SplitRenderer_quant_code( overhead_bits = pBits->bits_written; - ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->dof, IVAS_SPLIT_REND_DOF_BITS ); - ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->hq_mode, IVAS_SPLIT_REND_HQ_MODE_BITS ); - ivas_split_rend_bitstream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, IVAS_SPLIT_REND_ROT_AXIS_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS ); + + rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits ); + if ( num_bits > 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits ); + } + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS ); /* code ref pose*/ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) @@ -1084,29 +1142,28 @@ static void ivas_SplitRenderer_quant_code( Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); angle = (int16_t) roundf( head_pos_euler.x ); angle += 180; - ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); angle = (int16_t) roundf( head_pos_euler.y ); angle += 180; - ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); angle = (int16_t) roundf( head_pos_euler.z ); angle += 180; - ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); } - ivas_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, + isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw, - d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands ); + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats ); quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */ get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw, - pred_quant_pnts_yaw, - d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits ); + pred_quant_pnts_yaw, d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits ); for ( q = 0; q < num_quant_strats; q++ ) { @@ -1120,20 +1177,20 @@ static void ivas_SplitRenderer_quant_code( { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); + isar_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); } for ( ; b < pred_real_bands_yaw[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); + isar_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); } for ( b = 0; b < d_bands_yaw[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); + isar_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); } } else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) @@ -1141,7 +1198,7 @@ static void ivas_SplitRenderer_quant_code( for ( b = 0; b < bands_pitch[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); + isar_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); } } else @@ -1149,12 +1206,12 @@ static void ivas_SplitRenderer_quant_code( for ( b = 0; b < pred_imag_bands_roll[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); + isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); } for ( ; b < pred_real_bands_roll[q]; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); + isar_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); } } } @@ -1163,11 +1220,11 @@ static void ivas_SplitRenderer_quant_code( /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/ start_bit = pBits->bits_written; - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); - ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); huff_bits = pBits->bits_written; - ivas_SplitRenderer_code_md_huff( + isar_SplitRenderer_code_md_huff( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, @@ -1188,12 +1245,11 @@ static void ivas_SplitRenderer_quant_code( { pBits->bits_written = start_bit; - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); - ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); - ivas_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], - pred_quant_pnts_yaw[q], - d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); + isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); } break; } @@ -1276,25 +1332,26 @@ static void ivas_SplitRenderer_quant_code( } } } -#endif +#endif return; } /*------------------------------------------------------------------------- - * Function ivas_SplitRenderer_GetRotMd() + * Function isar_SplitRenderer_GetRotMd() * * *------------------------------------------------------------------------*/ -void ivas_SplitRenderer_GetRotMd( - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +static void isar_SplitRenderer_GetRotMd( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ const int16_t low_res, - const int16_t ro_md_flag ) + const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */ +) { float cov_ii_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_oo_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -1305,9 +1362,9 @@ void ivas_SplitRenderer_GetRotMd( int16_t real_only = 0; int16_t pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes, ch_s_idx1, ch_s_idx2; int16_t num_md_bands, num_poses; - const int16_t *pBand_grouping = ivas_split_rend_band_grouping; + const int16_t *pBand_grouping = isar_split_rend_band_grouping; - push_wmops( "ivas_SplitRenderer_GetRotMd" ); + push_wmops( "isar_SplitRenderer_GetRotMd" ); num_md_bands = MAX_SPLIT_REND_MD_BANDS; num_poses = pMultiBinPoseData->num_poses; @@ -1344,6 +1401,13 @@ void ivas_SplitRenderer_GetRotMd( /* compute rotated signal covariance */ for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL ) + { + if ( b >= SPLIT_REND_RO_MD_BAND_THRESH ) + { + real_only = 1; + } + } ch_s_idx2 = ( pos_idx + 1 ) * BINAURAL_CHANNELS; ComputeBandedCrossCov( Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx1, Cldfb_RealBuffer_Ref_Binaural, Cldfb_ImagBuffer_Ref_Binaural, ch_s_idx2, cov_io_re, cov_io_im, BINAURAL_CHANNELS, pBand_grouping, num_slots, start_slot_idx, b, real_only ); @@ -1360,27 +1424,28 @@ void ivas_SplitRenderer_GetRotMd( /*------------------------------------------------------------------------- - * Function ivas_rend_CldfbSplitPreRendProcess() + * Function isar_rend_CldfbSplitPreRendProcess() * * *------------------------------------------------------------------------*/ -void ivas_rend_CldfbSplitPreRendProcess( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - const IVAS_QUATERNION headPosition, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t target_md_bits, - const int16_t low_res_pre_rend_rot, - const int16_t ro_md_flag ) +void isar_rend_CldfbSplitPreRendProcess( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t target_md_bits, /* i : ISAR MD bitrate */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t ro_md_flag /* i : real only metadata for yaw flag */ +) { - push_wmops( "ivas_rend_CldfbSplitPreRendProcess" ); + push_wmops( "isar_rend_CldfbSplitPreRendProcess" ); - ivas_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag ); + isar_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag ); - ivas_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits ); + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits ); #ifdef SPLIT_POSE_CORRECTION_DEBUG float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; @@ -1461,7 +1526,7 @@ void ivas_rend_CldfbSplitPreRendProcess( mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); - ivas_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 ); + isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 ); { float *pOut[2]; @@ -1479,28 +1544,28 @@ void ivas_rend_CldfbSplitPreRendProcess( /*------------------------------------------------------------------------- - * Function ivas_splitBinPreRendOpen() + * Function isar_splitBinPreRendOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinPreRendOpen( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, /* i/o: binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* o : pose correction data handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , const int32_t output_Fs #endif ) { - BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG ivas_error error; int16_t ch; #endif int16_t pos_idx, sf_idx, bandIdx; - if ( ( hBinRend = (BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) + if ( ( hBinRend = (ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( ISAR_BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) ); } @@ -1524,8 +1589,8 @@ ivas_error ivas_splitBinPreRendOpen( } } } -#endif +#endif for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) { for ( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ ) @@ -1541,16 +1606,16 @@ ivas_error ivas_splitBinPreRendOpen( set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); - ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); #ifdef SPLIT_POSE_CORRECTION_DEBUG ivas_error error; - if ( ( error = ivas_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) { return error; } -#endif +#endif *hBinHrSplitPreRend = hBinRend; return IVAS_ERR_OK; @@ -1558,13 +1623,14 @@ ivas_error ivas_splitBinPreRendOpen( /*------------------------------------------------------------------------- - * Function ivas_splitBinPreRendClose() + * Function isar_splitBinPreRendClose() * * *------------------------------------------------------------------------*/ -void ivas_splitBinPreRendClose( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */ +) { if ( ( *hBinHrSplitPreRend ) != NULL ) { @@ -1585,7 +1651,7 @@ void ivas_splitBinPreRendClose( } #endif #ifdef SPLIT_POSE_CORRECTION_DEBUG - ivas_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); + isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); #endif free( ( *hBinHrSplitPreRend ) ); @@ -1597,99 +1663,48 @@ void ivas_splitBinPreRendClose( /*-------------------------------------------------------------------------* - * ivas_set_split_rend_ht_setup() + * isar_set_split_rend_ht_setup() * * *-------------------------------------------------------------------------*/ -void ivas_set_split_rend_ht_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ) -{ - int16_t sf, i, j; - if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) - { - hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; - - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------------* - * ivas_set_split_rend_setup() - * - * Setup IVAS split rendering - *-------------------------------------------------------------------------*/ - -ivas_error ivas_set_split_rend_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - uint8_t *splitRendBitsBuf ) +void isar_set_split_rend_ht_setup( + SPLIT_REND_WRAPPER *hSplitrend, /* i/o: Split renderer pre-renderer handle */ + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], /* i/o: External orientation in quaternions */ + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] /* o : real-space rotation matrix */ +) { int16_t sf, i, j; - if ( ( hSplitBinRend->hSplitRendBits = (IVAS_SPLIT_REND_BITS_HANDLE) malloc( sizeof( IVAS_SPLIT_REND_BITS_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split renderer Bits buffer\n" ) ); - } - - hSplitBinRend->hSplitRendBits->bits_buf = splitRendBitsBuf; - hSplitBinRend->hSplitRendBits->bits_read = 0; - hSplitBinRend->hSplitRendBits->bits_written = 0; - hSplitBinRend->hSplitRendBits->buf_len = IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; - hSplitBinRend->hSplitRendBits->codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hSplitBinRend->hSplitRendBits->pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - hSplitBinRend->hSplitRendBits->codec_frame_size_ms = 0; - - - if ( ( hSplitBinRend->hMultiBinCldfbData = (IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); - } - - ivas_renderSplitGetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, hCombinedOrientationData->sr_pose_pred_axis ); - - if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) { - hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; + Quaternions[sf] = Quaternions[0]; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { - hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; + Rmat[sf][i][j] = Rmat[0][i][j]; } } } } - return IVAS_ERR_OK; + return; } /*------------------------------------------------------------------------- - * Function ivas_init_split_rend_handles() + * Function isar_init_split_rend_handles() * * *------------------------------------------------------------------------*/ -void ivas_init_split_rend_handles( - SPLIT_REND_WRAPPER *hSplitRendWrapper ) +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer pre-renderer handle */ +) { int16_t i; @@ -1698,18 +1713,13 @@ void ivas_init_split_rend_handles( hSplitRendWrapper->hSplitBinLCLDEnc = NULL; hSplitRendWrapper->hLc3plusEnc = NULL; - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) - { - hSplitRendWrapper->hTdRendHandles[i] = NULL; - } - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) { hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL; } hSplitRendWrapper->lc3plusDelaySamples = 0; - ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); return; } @@ -1721,37 +1731,52 @@ void ivas_init_split_rend_handles( * *------------------------------------------------------------------------*/ -static ivas_error split_renderer_open_lc3plus( - SPLIT_REND_WRAPPER *hSplitRendWrapper, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t OutSampleRate, - const int16_t num_subframes ) +ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i/o: Split renderer pre-renderer handle */ + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const IVAS_RENDER_FRAMESIZE isar_frame_size /* i : IVAS frame size */ +) { ivas_error error; int16_t i, delayBufferLength; LC3PLUS_CONFIG config; + int16_t isar_frame_size_ms; + + if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Check configuration validity */ + if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" ); + } config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; - config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; - config.samplerate = OutSampleRate; + config.samplerate = output_Fs; + + config.isar_frame_duration_us = isar_frame_size_ms * 1000; + config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 ); config.channels = BINAURAL_CHANNELS; - if ( ( error = IVAS_LC3PLUS_ENC_Open( config, ivas_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.ivas_frame_duration_us / 1000 ) ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_LC3PLUS_ENC_Open( config, isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, config.channels, config.lc3plus_frame_duration_us ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) { return error; } /* This returns delay of entire LC3plus chain (enc + dec) */ - if ( ( error = IVAS_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) { return error; } /* Alocate buffers for delay compensation */ - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) + if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - delayBufferLength = (int16_t) ( OutSampleRate / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples ); + delayBufferLength = (int16_t) ( output_Fs / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples ); for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) { if ( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL ) @@ -1765,8 +1790,8 @@ static ivas_error split_renderer_open_lc3plus( else { /* Delay is always expected to be exactly 2 CLDFB columns */ - assert( hSplitRendWrapper->lc3plusDelaySamples % ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 ); - assert( hSplitRendWrapper->lc3plusDelaySamples / ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 ); + assert( hSplitRendWrapper->lc3plusDelaySamples % ( output_Fs / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 ); + assert( hSplitRendWrapper->lc3plusDelaySamples / ( output_Fs / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 ); delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX; for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) @@ -1784,233 +1809,18 @@ static ivas_error split_renderer_open_lc3plus( } -/*------------------------------------------------------------------------- - * Function ivas_split_renderer_open() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_split_renderer_open( - SPLIT_REND_WRAPPER *hSplitRendWrapper, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t OutSampleRate, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t num_subframes ) -{ - ivas_error error, ch, num_ch; -#ifndef SPLIT_REND_WITH_HEAD_ROT - CLDFB_TYPE cldfbMode; -#endif - uint8_t isCldfbNeeded = 0; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif - - if ( ( error = ivas_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( cldfb_in_flag == 0 ) - { - isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif - } - else if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - isCldfbNeeded = 1; -#else - isCldfbNeeded = 1; - cldfbMode = CLDFB_SYNTHESIS; -#endif - } - else if ( pcm_out_flag && cldfb_in_flag ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - isCldfbNeeded = 1; -#else - isCldfbNeeded = 1; - cldfbMode = CLDFB_SYNTHESIS; -#endif - } - - hSplitRendWrapper->hCldfbHandles = NULL; - - if ( isCldfbNeeded ) - { - if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); - } - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; - } -#endif - - num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; - - for ( ch = 0; ch < num_ch; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode, -#else - CLDFB_ANALYSIS, -#endif - OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#endif - } - - if ( pSplitRendConfig->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - if ( ( error = ivas_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - , - OutSampleRate -#endif - ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( pcm_out_flag == 0 ) - { - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) - { - if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - int16_t iNumBlocksPerFrame; - iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; - - if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_renderer_close() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_renderer_close( - SPLIT_REND_WRAPPER *hSplitBinRend ) -{ - int16_t i; - - if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) - { - ivas_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); - } - - if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) - { - ivas_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); - } - - if ( hSplitBinRend->hCldfbHandles != NULL ) - { - int16_t num_ch, ch; - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) - { - deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); - hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) - { - deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ); - hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; - } - } -#endif - - free( hSplitBinRend->hCldfbHandles ); - hSplitBinRend->hCldfbHandles = NULL; - } - - if ( hSplitBinRend->hLc3plusEnc != NULL ) - { - IVAS_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); - } - - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) - { - if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) - { - free( hSplitBinRend->lc3plusDelayBuffers[i] ); - hSplitBinRend->lc3plusDelayBuffers[i] = NULL; - } - } - - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) - { - if ( hSplitBinRend->hTdRendHandles[i] != NULL ) - { - hSplitBinRend->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &hSplitBinRend->hTdRendHandles[i] ); - } - } - - return; -} - - /*------------------------------------------------------------------------- * Function splitRendLc3plusEncodeAndWrite() * * *------------------------------------------------------------------------*/ -static ivas_error splitRendLc3plusEncodeAndWrite( - SPLIT_REND_WRAPPER *hSplitBin, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t SplitRendBitRate, - float *in[] ) +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t available_bits, /* i : available bit-budget */ + float *in[] /* i/o: PCM in/out buffer */ +) { ivas_error error; int16_t i; @@ -2021,7 +1831,7 @@ static ivas_error splitRendLc3plusEncodeAndWrite( /* Find next byte boundary and zero-pad to it */ while ( pBits->bits_written % 8 != 0 ) { - ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); } for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) @@ -2029,47 +1839,54 @@ static ivas_error splitRendLc3plusEncodeAndWrite( channel_ptrs[i] = in[i]; } - if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK ) { return error; } - ivas_split_rend_bitstream_write_int32( pBits, ivas_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); + if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + { + return error; + } /* Write bitstream */ - if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) { return error; } pBits->bits_written += 8 * lc3plusBitstreamSize; - pBits->codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; + pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 ); + pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 ); + return IVAS_ERR_OK; } /*------------------------------------------------------------------------- - * Function ivas_renderMultiTDBinToSplitBinaural() + * Function isar_renderMultiTDBinToSplitBinaural() * * *------------------------------------------------------------------------*/ -static ivas_error ivas_renderMultiTDBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - const int16_t codec_frame_size_ms, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int16_t max_bands, - float *in[], - const int16_t low_res_pre_rend_rot, - const int16_t pcm_out_flag, - const int16_t ro_md_flag ) +ivas_error isar_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const int16_t isar_frame_size_ms, /* i : ISAR bit stream frame size in ms */ + const int16_t codec_frame_size_ms, /* i : ISAR frame length in ms */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int16_t max_bands, /* i : CLDFB bands */ + float *in[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t ro_md_flag /* i : real only metadata for yaw flag */ +) { ivas_error error; - int32_t bit_len, available_bits, target_md_bits, actual_md_bits; + int32_t bit_len, available_bits, target_md_bits; int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -2078,7 +1895,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( int16_t i; int32_t num_slots; - push_wmops( "ivas_renderMultiTDBinToSplitBinaural" ); + push_wmops( "isar_renderMultiTDBinToSplitBinaural" ); error = IVAS_ERR_OK; num_poses = hSplitBin->multiBinPoseData.num_poses; @@ -2106,10 +1923,9 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( } } - actual_md_bits = pBits->bits_written; - if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) + if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) { - num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); + num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; /* CLDFB Analysis*/ @@ -2143,32 +1959,39 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( } } - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; - - actual_md_bits = pBits->bits_written; + target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; - ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); } if ( pcm_out_flag == 0 ) { pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec = useLc3plus ? IVAS_SPLIT_REND_CODEC_LC3PLUS : IVAS_SPLIT_REND_CODEC_LCLD; + pBits->codec = useLc3plus ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD; if ( !useLc3plus ) { available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); - actual_md_bits = pBits->bits_written - actual_md_bits; - available_bits -= actual_md_bits; + available_bits -= pBits->bits_written; pBits->codec_frame_size_ms = codec_frame_size_ms; + pBits->isar_frame_size_ms = isar_frame_size_ms; - ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } else { - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) + if ( pBits->pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + available_bits = isar_get_lc3plus_bitrate( SplitRendBitRate, hSplitBin->multiBinPoseData.poseCorrectionMode, hSplitBin->hLc3plusEnc->config.channels, hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us ) / FRAMES_PER_SEC; + } + else + { + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + } + + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK ) { return error; } @@ -2177,7 +2000,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( else { pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; } /*zero pad*/ @@ -2193,14 +2016,14 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( } else { - bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; bit_len = SplitRendBitRate * bit_len / 1000; } } while ( pBits->bits_written < bit_len ) { - ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); } pop_wmops(); @@ -2215,10 +2038,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( * *------------------------------------------------------------------------*/ -static void lc3plusTimeAlignCldfbPoseCorr( - SPLIT_REND_WRAPPER *hSplitBin, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) +void lc3plusTimeAlignCldfbPoseCorr( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: Binaural signals, real part */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* ii/: Binaural signals, imag. part */ +) { float Cldfb_In_BinReal_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; float Cldfb_In_BinImag_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; @@ -2240,7 +2064,6 @@ static void lc3plusTimeAlignCldfbPoseCorr( } /* Delay existing columns by 2 slots */ - /*TODO : shouldnt the delay be 7.5 ms ? 5ms + LC3plus delay */ for ( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx ) { mvr2r( Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinReal[pose * BINAURAL_CHANNELS + ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); @@ -2269,170 +2092,3 @@ static void lc3plusTimeAlignCldfbPoseCorr( return; } - - -/*------------------------------------------------------------------------- - * Function ivas_renderMultiBinToSplitBinaural() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_renderMultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_CODEC splitCodec, - int16_t codec_frame_size_ms, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t max_bands, - float *output[], - const int16_t low_res_pre_rend_rot, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t ro_md_flag ) -{ - ivas_error error; - int32_t bit_len, target_md_bits, actual_md_bits, available_bits; - - error = IVAS_ERR_OK; - push_wmops( "ivas_renderMultiBinToSplitBinaural" ); - - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData ); - set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); - } - - /* Needs to be done at runtime. If this was in another API function, - * there would be no guarantee that the user did not change - * the split rendering config before calling the main rendering function */ - if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - - if ( cldfb_in_flag == 0 ) - { - /*TD input*/ - /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ - error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag, ro_md_flag ); - - pop_wmops(); - return error; - } - - if ( splitCodec == IVAS_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - /* Time-align pose correction to delay of LC3plus */ - lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); - } - - actual_md_bits = pBits->bits_written; - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; - - actual_md_bits = pBits->bits_written; - - ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); - } - - if ( pcm_out_flag == 0 ) - { - pBits->codec = splitCodec; - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - - if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); - actual_md_bits = pBits->bits_written - actual_md_bits; - available_bits -= actual_md_bits; - pBits->codec_frame_size_ms = codec_frame_size_ms; - ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); - } - else - { - int16_t ch, slot_idx, num_slots, ivas_fs; - ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; - num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20; - /* CLDFB synthesis of main pose */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; - float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; - - for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) - { - Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; - Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; - } -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); -#else - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); -#endif - } - - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - else - { - int16_t ch, slot_idx; - /* CLDFB synthesis of main pose */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; - float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; - - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) - { - Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; - Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; - } - -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); -#else - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); -#endif - } - - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; - } - - /*zero pad*/ - if ( pcm_out_flag ) - { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; - } - else - { - if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); - } - else - { - bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; - bit_len = SplitRendBitRate * bit_len / 1000; - } - } - - while ( pBits->bits_written < bit_len ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); - } - - pop_wmops(); - - return error; -} -#endif diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c similarity index 67% rename from lib_rend/ivas_splitRenderer_utils.c rename to lib_isar/isar_splitRenderer_utils.c index da9ba62801bda41292f9cdcb08695b481fd19de4..40c2f73951db073ebd3eb93ba761bace9951972a 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_isar/isar_splitRenderer_utils.c @@ -32,18 +32,11 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "ivas_prot.h" -#include "prot.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "ivas_rom_rend.h" -#include "ivas_rom_com.h" -#include "ivas_rom_dec.h" -#include "ivas_rom_binauralRenderer.h" -#include "lib_rend.h" -#include "ivas_prot_rend.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_post_rend.h" +#include "isar_prot.h" #ifdef DEBUGGING #include "debug.h" #endif @@ -51,12 +44,12 @@ /*------------------------------------------------------------------------- - * Function ivas_mat_mult_2by2_complex() + * Function isar_mat_mult_2by2_complex() * * *------------------------------------------------------------------------*/ -void ivas_mat_mult_2by2_complex( +void isar_mat_mult_2by2_complex( float in_re1[2][2], float in_im1[2][2], float in_re2[2][2], @@ -86,33 +79,13 @@ void ivas_mat_mult_2by2_complex( /*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_init() + * Function isar_split_rend_huffman_dec_init_min_max_len() * * *------------------------------------------------------------------------*/ -void ivas_split_rend_bitstream_init( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t buf_len_bytes, - uint8_t *pbuf ) -{ - pBits->bits_buf = pbuf; - pBits->buf_len = buf_len_bytes; - pBits->bits_read = 0; - pBits->bits_written = 0; - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_huffman_dec_init_min_max_len() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_rend_huffman_dec_init_min_max_len( - ivas_split_rend_huffman_cfg_t *p_huff_cfg ) +static void isar_split_rend_huffman_dec_init_min_max_len( + isar_split_rend_huffman_cfg_t *p_huff_cfg ) { int16_t i, code_len; const int32_t *codebook; @@ -166,14 +139,14 @@ static int16_t is_idx_present( /*------------------------------------------------------------------------- - * Function ivas_split_huff_get_idx_trav_list() + * Function isar_split_huff_get_idx_trav_list() * * *------------------------------------------------------------------------*/ -static void ivas_split_huff_get_idx_trav_list( +static void isar_split_huff_get_idx_trav_list( int16_t *idx_list, - ivas_split_rend_huffman_cfg_t *p_huff_cfg ) + isar_split_rend_huffman_cfg_t *p_huff_cfg ) { int16_t i, j, min_idx; int32_t min_bits; @@ -206,49 +179,49 @@ static void ivas_split_huff_get_idx_trav_list( /*------------------------------------------------------------------------- - * Function ivas_split_rend_init_huff_cfg() + * Function isar_split_rend_init_huff_cfg() * * *------------------------------------------------------------------------*/ -void ivas_split_rend_init_huff_cfg( - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) +void isar_split_rend_init_huff_cfg( + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) { - pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0]; - pHuff_cfg->pred[0].sym_len = IVAS_SPLIT_REND_PRED_31QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] ); - ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] ); + pHuff_cfg->pred[0].codebook = &isar_split_rend_huff_pred31_consts[0][0]; + pHuff_cfg->pred[0].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] ); + isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[0], &pHuff_cfg->pred[0] ); pHuff_cfg->pred_base2_code_len[0] = (int16_t) ceilf( log2f( pHuff_cfg->pred[0].sym_len ) ); - pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0]; - pHuff_cfg->pred[1].sym_len = IVAS_SPLIT_REND_PRED_63QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] ); - ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] ); + pHuff_cfg->pred[1].codebook = &isar_split_rend_huff_pred63_consts[0][0]; + pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] ); + isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav[1], &pHuff_cfg->pred[1] ); pHuff_cfg->pred_base2_code_len[1] = (int16_t) ceilf( log2f( pHuff_cfg->pred[1].sym_len ) ); - pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0]; - pHuff_cfg->pred_roll.sym_len = IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll ); - ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll ); + pHuff_cfg->pred_roll.codebook = &isar_split_rend_huff_roll_pred_consts[0][0]; + pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS; + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll ); + isar_split_huff_get_idx_trav_list( pHuff_cfg->pred_roll_idx_trav, &pHuff_cfg->pred_roll ); pHuff_cfg->pred_roll_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->pred_roll.sym_len ) ); - pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0]; - pHuff_cfg->gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); - ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd ); + pHuff_cfg->gd.codebook = &isar_split_rend_huff_d_consts[0][0]; + pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); + isar_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd ); pHuff_cfg->gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->gd.sym_len ) ); - pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0]; - pHuff_cfg->p_gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); - ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd ); + pHuff_cfg->p_gd.codebook = &isar_split_rend_huff_p_d_consts[0][0]; + pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); + isar_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd ); pHuff_cfg->p_gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd.sym_len ) ); - pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0]; - pHuff_cfg->p_gd_diff.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); - ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff ); + pHuff_cfg->p_gd_diff.codebook = &isar_split_rend_huff_p_d_diff_consts[0][0]; + pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + isar_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); + isar_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff ); pHuff_cfg->p_gd_diff_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd_diff.sym_len ) ); return; @@ -263,7 +236,8 @@ void ivas_split_rend_init_huff_cfg( void set_fix_rotation_mat( float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +) { float yaw_a, cos_yaw, sin_yaw; int16_t pos_idx; @@ -292,8 +266,9 @@ void set_fix_rotation_mat( *------------------------------------------------------------------------*/ void set_pose_types( - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], /* o : ISAR pose type */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i : pose correction data handle */ +) { int16_t pos_idx; @@ -323,7 +298,7 @@ void set_pose_types( * *------------------------------------------------------------------------*/ -int16_t wrap_a( +static int16_t wrap_a( int16_t val, const int16_t min_val, const int16_t max_val ) @@ -343,12 +318,12 @@ int16_t wrap_a( /*------------------------------------------------------------------------- - * Function ivas_SplitRenderer_getdiagdiff() + * Function isar_SplitRenderer_getdiagdiff() * * *------------------------------------------------------------------------*/ -void ivas_SplitRenderer_getdiagdiff( +void isar_SplitRenderer_getdiagdiff( int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], const int16_t sign, @@ -367,22 +342,24 @@ void ivas_SplitRenderer_getdiagdiff( /*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_read_int32() + * Function ISAR_SPLIT_REND_BITStream_read_int32() * * *------------------------------------------------------------------------*/ -int32_t ivas_split_rend_bitstream_read_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits ) +/*! r: parameter value */ +int32_t ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t bits /* i : number of bits to be read */ +) { int32_t val, k, bit_val; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); assert( bits <= 32 ); -#endif +#endif /* write bit by bit */ val = 0; for ( k = bits - 1; k >= 0; k-- ) @@ -397,15 +374,16 @@ int32_t ivas_split_rend_bitstream_read_int32( /*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_write_int32() + * Function ISAR_SPLIT_REND_BITStream_write_int32() * * *------------------------------------------------------------------------*/ -void ivas_split_rend_bitstream_write_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits ) +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t val, /* i : parameter value */ + const int32_t bits /* i : number of bits to be written */ +) { int32_t mask, k; @@ -439,12 +417,12 @@ void ivas_split_rend_bitstream_write_int32( #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG /*------------------------------------------------------------------------- - * ivas_mat_mult_2by2_complex() + * isar_log_cldfb2wav_data() * * *------------------------------------------------------------------------*/ -void ivas_log_cldfb2wav_data( +void isar_log_cldfb2wav_data( float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], HANDLE_CLDFB_FILTER_BANK *cldfbSyn, @@ -484,14 +462,16 @@ void ivas_log_cldfb2wav_data( /*------------------------------------------------------------------------- - * Function ivas_get_split_rend_md_target_brate() + * Function isar_get_split_rend_md_target_brate() * * *------------------------------------------------------------------------*/ -int32_t ivas_get_split_rend_md_target_brate( - const int32_t SplitRendBitRate, - const int16_t pcm_out_flag ) +/*! r: ISAR MD bitrate */ +int32_t isar_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +) { int32_t md_bitrate; @@ -530,16 +510,18 @@ int32_t ivas_get_split_rend_md_target_brate( /*------------------------------------------------------------------------- - * Function ivas_get_lcld_bitrate() + * Function isar_get_lcld_bitrate() * * *------------------------------------------------------------------------*/ -int32_t ivas_get_lcld_bitrate( - const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) +/*! r: LCLD codec bitrate */ +int32_t isar_get_lcld_bitrate( + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode /* i : ISAR pose correction mode */ +) { - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { switch ( SplitRendBitRate ) { @@ -571,137 +553,42 @@ int32_t ivas_get_lcld_bitrate( /*------------------------------------------------------------------------- - * Function ivas_get_lc3plus_bitrate() - * - * - *------------------------------------------------------------------------*/ - -int32_t ivas_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) -{ - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - int32_t inBandMdBps = (int32_t) ( 8 * 1000 / split_prerender_frame_size_ms ); - return ivas_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps; - } - - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) - { - return SplitRendBitRate; - } - - /* Should not be reached */ - assert( 0 ); - return -1; -} - - -/*------------------------------------------------------------------------- - * Function ivas_get_lc3plus_bitrate_id() - * - * - *------------------------------------------------------------------------*/ - -int8_t ivas_get_lc3plus_bitrate_id( - const int32_t SplitRendBitRate ) -{ - switch ( SplitRendBitRate ) - { - case SPLIT_REND_768k: - { - return 4; - } - case SPLIT_REND_512k: - { - return 3; - } - case SPLIT_REND_384k: - { - return 2; - } - case SPLIT_REND_320k: - { - return 1; - } - case SPLIT_REND_256k: - { - return 0; - } - default: - { - break; - } - } - - return -1; -} - - -/*------------------------------------------------------------------------- - * Function ivas_mat_mult_2by2_complex() + * Function isar_get_lc3plus_bitrate() * * *------------------------------------------------------------------------*/ -int32_t ivas_get_lc3plus_size_from_id( - const int8_t SplitRendBitRateId, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, /* i : ISAR pose correction mode */ + const int32_t nChannels, /* i : number of channels */ + const int32_t codecFrameDurationUs /* i : ISAR frame length in us */ +) { int32_t bitrate; - switch ( SplitRendBitRateId ) + bitrate = isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ); + + /* Check for LC3plus LEA 48_6 LC3 compatibility mode signalling */ + if ( ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE == poseCorrectionMode && bitrate == 256000 && nChannels == 2 && codecFrameDurationUs == 10000 ) { - case 4: - { - bitrate = SPLIT_REND_768k; - break; - } - case 3: - { - bitrate = SPLIT_REND_512k; - break; - } - case 2: - { - bitrate = SPLIT_REND_384k; - break; - } - case 1: - { - bitrate = SPLIT_REND_320k; - break; - } - case 0: - { - bitrate = SPLIT_REND_256k; - break; - } - default: - { - bitrate = -1; - break; - } + bitrate = 2 * 126000; } - bitrate = ivas_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms ); - - /* Return size in bytes */ - return (int32_t) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 ); + return bitrate; } /*------------------------------------------------------------------------- - * Function ivas_split_rend_validate_config() + * Function isar_split_rend_validate_config() * * *------------------------------------------------------------------------*/ -ivas_error ivas_split_rend_validate_config( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t is_pcm_out ) +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renderer config */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +) { /* Valid DOF range is 0-3 */ if ( pSplitRendConfig->dof < 0 || pSplitRendConfig->dof > 3 ) @@ -710,33 +597,33 @@ ivas_error ivas_split_rend_validate_config( } /* Only CLDFB pose correction supports HQ mode */ - if ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && pSplitRendConfig->hq_mode != 0 ) + if ( pSplitRendConfig->poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && pSplitRendConfig->hq_mode != 0 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Only CLDFB pose correction supports HQ mode" ); } /* Split rendering with no pose correction - 0 DOF and pose correction NONE must only ever be set together */ - if ( ( pSplitRendConfig->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) || - ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof == 0 ) ) + if ( ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) || + ( pSplitRendConfig->poseCorrectionMode != ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof == 0 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "0 DOF and pose correction NONE must only ever be set together" ); } if ( pSplitRendConfig->codec_frame_size_ms != 0 ) /* 0 means "default for current codec", will be set to actual value at a later stage */ { - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 ) + if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); } - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 ) ) + if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" ); } } /* Validate bitrate */ - if ( is_pcm_out == 0 ) + if ( pcm_out_flag == 0 ) { switch ( pSplitRendConfig->splitRendBitRate ) { @@ -755,13 +642,8 @@ ivas_error ivas_split_rend_validate_config( break; case SPLIT_REND_384k: case SPLIT_REND_512k: - /* Always valid */ - break; case SPLIT_REND_768k: - if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" ); - } + /* Always valid */ break; default: return IVAS_ERR_LC3PLUS_INVALID_BITRATE; @@ -771,23 +653,23 @@ ivas_error ivas_split_rend_validate_config( { if ( pSplitRendConfig->dof == 1 ) { - if ( pSplitRendConfig->splitRendBitRate < 50000 ) + if ( pSplitRendConfig->splitRendBitRate < 34000 ) { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" ); } } else if ( pSplitRendConfig->dof == 2 ) { - if ( pSplitRendConfig->splitRendBitRate < 66000 ) + if ( pSplitRendConfig->splitRendBitRate < 50000 ) { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" ); } } else if ( pSplitRendConfig->dof == 3 ) { - if ( pSplitRendConfig->splitRendBitRate < 128000 ) + if ( pSplitRendConfig->splitRendBitRate < 82000 ) { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 82 kbps" ); } } } @@ -797,39 +679,37 @@ ivas_error ivas_split_rend_validate_config( /*------------------------------------------------------------------------- - * Function ivas_split_rend_get_quant_params() + * Function isar_split_rend_get_quant_params() * * *------------------------------------------------------------------------*/ -void ivas_split_rend_get_quant_params( +void isar_split_rend_get_quant_params( const int16_t num_md_bands, - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t *num_quant_strats, - int16_t *num_complex_bands ) + int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t ro_flag, + int16_t *num_quant_strats ) { int16_t q; - *num_quant_strats = IVAS_SPLIT_REND_NUM_QUANT_STRATS; - *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; - assert( *num_complex_bands <= num_md_bands ); + *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS; - pred_quant_pnts_yaw[0] = IVAS_SPLIT_REND_PRED_63QUANT_PNTS; - pred_quantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_Q_STEP; - pred_1byquantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_1BYQ_STEP; + pred_quant_pnts_yaw[0] = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; + pred_quantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_Q_STEP; + pred_1byquantstep_yaw[0] = ISAR_SPLIT_REND_PRED63_1BYQ_STEP; for ( q = 1; q < *num_quant_strats; q++ ) { - pred_quant_pnts_yaw[q] = IVAS_SPLIT_REND_PRED_31QUANT_PNTS; - pred_quantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_Q_STEP; - pred_1byquantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_1BYQ_STEP; + pred_quant_pnts_yaw[q] = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; + pred_quantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_Q_STEP; + pred_1byquantstep_yaw[q] = ISAR_SPLIT_REND_PRED31_1BYQ_STEP; } for ( q = 0; q < *num_quant_strats; q++ ) @@ -837,15 +717,27 @@ void ivas_split_rend_get_quant_params( pred_real_bands_yaw[q] = num_md_bands; pred_real_bands_roll[q] = num_md_bands; } - pred_imag_bands_yaw[0] = num_md_bands; - pred_imag_bands_roll[0] = num_md_bands; - pred_imag_bands_yaw[1] = num_md_bands; - pred_imag_bands_roll[1] = num_md_bands; - for ( q = 2; q < *num_quant_strats; q++ ) + if ( ro_flag ) + { + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH; + } + } + else + { + for ( q = 0; q < *num_quant_strats - 2; q++ ) + { + pred_imag_bands_yaw[q] = num_md_bands; + } + pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH; + pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW; + } + + for ( q = 0; q < *num_quant_strats; q++ ) { - pred_imag_bands_yaw[q] = ( q < ( *num_quant_strats - 1 ) ) ? num_md_bands : *num_complex_bands; - pred_imag_bands_roll[q] = *num_complex_bands; + pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH; } for ( q = 0; q < *num_quant_strats; q++ ) @@ -859,15 +751,113 @@ void ivas_split_rend_get_quant_params( /*------------------------------------------------------------------------- - * Function ivas_renderSplitGetMultiBinPoseData() + * Function isar_renderSplitGetRot_axisNumBits() + * + * + *------------------------------------------------------------------------*/ + +int16_t isar_renderSplitGetRot_axisNumBits( + const int16_t dof ) +{ + int16_t num_bits; + if ( dof < 3 ) + { + num_bits = 2; + } + else + { + num_bits = 0; + } + + return num_bits; +} + + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisFromCode() + * + * + *------------------------------------------------------------------------*/ + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const int16_t dof, + const int16_t code ) +{ + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + + if ( dof == 1 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else if ( dof == 2 ) + { + if ( code == 0 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH; + } + } + else + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS; + } + + return rot_axis; +} + + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetCodeFromRot_axis() + * + * + *------------------------------------------------------------------------*/ + +int16_t isar_renderSplitGetCodeFromRot_axis( + const int16_t dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + int16_t *num_bits ) +{ + int16_t code = 0; + + if ( dof == 1 ) + { + code = (int16_t) rot_axis; + } + else if ( dof == 2 ) + { + if ( rot_axis == DEFAULT_AXIS ) + { + code = (int16_t) rot_axis; + } + else + { + code = (int16_t) ( rot_axis - YAW_PITCH ) + 1; + } + } + else + { + code = (int16_t) DEFAULT_AXIS; + } + *num_bits = isar_renderSplitGetRot_axisNumBits( dof ); + + return code; +} + + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetMultiBinPoseData() * * *------------------------------------------------------------------------*/ -void ivas_renderSplitGetMultiBinPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_SPLIT_REND_ROT_AXIS rot_axis ) +void isar_renderSplitGetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +) { int16_t pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; const float *relative_yaw_angles; @@ -887,9 +877,9 @@ void ivas_renderSplitGetMultiBinPoseData( num_roll_poses = 0; /* defaults for all DOF except 3DOF HQ */ - relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq; - relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq; - relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq; + relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = isar_split_rend_relative_roll_pos_angles_hq; if ( pSplit_rend_config->dof == 1 ) { @@ -922,15 +912,12 @@ void ivas_renderSplitGetMultiBinPoseData( switch ( rot_axis ) { case DEFAULT_AXIS: - case YAW: - case PITCH: case YAW_PITCH: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; break; } - case ROLL: case YAW_ROLL: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; @@ -953,18 +940,18 @@ void ivas_renderSplitGetMultiBinPoseData( { if ( pSplit_rend_config->hq_mode == 1 ) { - relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq; - relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq; - relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq; + relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = isar_split_rend_relative_roll_pos_angles_hq; num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; } else { - relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles; - relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles; - relative_roll_angles = ivas_split_rend_relative_roll_pos_angles; + relative_yaw_angles = isar_split_rend_relative_yaw_pos_angles; + relative_pitch_angles = isar_split_rend_relative_pitch_pos_angles; + relative_roll_angles = isar_split_rend_relative_roll_pos_angles; num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; num_pitch_poses = 1; num_roll_poses = 1; @@ -998,19 +985,20 @@ void ivas_renderSplitGetMultiBinPoseData( /*------------------------------------------------------------------------- - * Function ivas_renderSplitUpdateNoCorrectionPoseData() + * Function isar_renderSplitUpdateNoCorrectionPoseData() * * *------------------------------------------------------------------------*/ -void ivas_renderSplitUpdateNoCorrectionPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +) { pMultiBinPoseData->num_poses = 1; assert( pSplit_rend_config->dof == 0 ); pMultiBinPoseData->dof = pSplit_rend_config->dof; - assert( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); + assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; return; @@ -1018,13 +1006,14 @@ void ivas_renderSplitUpdateNoCorrectionPoseData( /*------------------------------------------------------------------------- - * Function ivas_init_multi_bin_pose_data() + * Function isar_init_multi_bin_pose_data() * * *------------------------------------------------------------------------*/ -void ivas_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +void isar_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +) { int16_t pos_idx; @@ -1044,13 +1033,44 @@ void ivas_init_multi_bin_pose_data( /*------------------------------------------------------------------------- - * Function ivas_split_rend_choose_default_codec() + * Function isar_framesize_to_ms() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_framesize_to_ms( + const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ + int16_t *ms /* o : frame size in ms */ +) +{ + switch ( frame_size ) + { + case IVAS_RENDER_FRAMESIZE_5MS: + *ms = 5; + break; + case IVAS_RENDER_FRAMESIZE_10MS: + *ms = 10; + break; + case IVAS_RENDER_FRAMESIZE_20MS: + *ms = 20; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" ); + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_choose_default_codec() * * *------------------------------------------------------------------------*/ -ivas_error ivas_split_rend_choose_default_codec( - IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ +ivas_error isar_split_rend_choose_default_codec( + ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + int16_t *pIsar_frame_size_ms, /* i/o: pointer to ISAR frame size setting */ int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ @@ -1059,25 +1079,25 @@ ivas_error ivas_split_rend_choose_default_codec( { if ( pcm_out_flag == 0 ) { - if ( *pCodec == IVAS_SPLIT_REND_CODEC_DEFAULT ) + if ( *pCodec == ISAR_SPLIT_REND_CODEC_DEFAULT ) { - *pCodec = cldfb_in_flag ? IVAS_SPLIT_REND_CODEC_LCLD : IVAS_SPLIT_REND_CODEC_LC3PLUS; + *pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS; } } else { - *pCodec = IVAS_SPLIT_REND_CODEC_NONE; + *pCodec = ISAR_SPLIT_REND_CODEC_NONE; } if ( *pCodec_frame_size_ms == 0 ) /* codec frame size hasn't been set yet - use default for current configuration */ { switch ( *pCodec ) { - case IVAS_SPLIT_REND_CODEC_LCLD: + case ISAR_SPLIT_REND_CODEC_LCLD: *pCodec_frame_size_ms = num_subframes * 5; break; - case IVAS_SPLIT_REND_CODEC_LC3PLUS: - case IVAS_SPLIT_REND_CODEC_NONE: + case ISAR_SPLIT_REND_CODEC_LC3PLUS: + case ISAR_SPLIT_REND_CODEC_NONE: *pCodec_frame_size_ms = 5; break; default: @@ -1085,9 +1105,14 @@ ivas_error ivas_split_rend_choose_default_codec( } } + if ( *pIsar_frame_size_ms == 0 ) /* ISAR frame size hasn't been set yet - use default for current configuration */ + { + *pIsar_frame_size_ms = 20; + } + return IVAS_ERR_OK; } -#endif + /*-------------------------------------------------------------------* * Function get_bit() diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h new file mode 100644 index 0000000000000000000000000000000000000000..9835f3aeb2de6c837d804dcd67c3fafb9232f953 --- /dev/null +++ b/lib_isar/isar_stat.h @@ -0,0 +1,348 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef ISAR_STAT_H +#define ISAR_STAT_H + + +#include +#include "options.h" +#include "stat_com.h" +#include "ivas_stat_com.h" +#include "isar_lcld_prot.h" +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_dec.h" +#include "isar_cnst.h" + + +/*-------------------------------------------------------------------* + * ISAR post rend constants + *-------------------------------------------------------------------*/ + +#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) +#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) + +/*-------------------------------------------------------------------* + * ISAR post rend structs + *-------------------------------------------------------------------*/ + +/* binaural split rendering head rotation data structure */ +typedef struct ivas_binaural_head_rot_split_rendering_md_struct +{ + float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd; + float gd2; + int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t gd_idx; + int16_t gd2_idx; + +} BIN_HR_SPLIT_REND_MD, *BIN_HR_SPLIT_REND_MD_HANDLE; + +typedef struct ivas_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; + +} ivas_split_rend_huffman_cfg_t; + +typedef struct ivas_binaural_head_rot_split_rendering_huff_struct +{ + ivas_split_rend_huffman_cfg_t pred[2]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_base2_code_len[2]; + ivas_split_rend_huffman_cfg_t pred_roll; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_base2_code_len; + ivas_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + ivas_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + ivas_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + +} BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +typedef struct ivas_binaural_head_rot_split_post_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; + float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; + +} BIN_HR_SPLIT_POST_REND, *BIN_HR_SPLIT_POST_REND_HANDLE; +#endif + +typedef struct ivas_binaural_head_rot_split_pre_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; + +typedef struct +{ + float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; + +} CLDFB_PLC, *CLDFB_PLC_HANDLE; + +typedef struct +{ + CLDFB_PLC CldfbPLC_state; + int16_t prev_bfi; + int16_t bf_count; + int16_t iNumSubSets; + +} SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE; + +typedef struct +{ + int8_t headRotEnabled; + IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + +} ISAR_POST_REND_HeadRotData; + +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; +#else + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; +#endif + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; + +} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; + +typedef struct isar_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; + +} isar_split_rend_huffman_cfg_t; + +typedef struct isar_binaural_head_rot_split_rendering_huff_struct +{ + isar_split_rend_huffman_cfg_t pred[2]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_base2_code_len[2]; + isar_split_rend_huffman_cfg_t pred_roll; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_base2_code_len; + isar_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + +} ISAR_BIN_HR_SPLIT_REND_HUFF, *ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE; + +/* binaural split rendering head rotation data structure */ +typedef struct isar_binaural_head_rot_split_rendering_md_struct +{ + float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float pred_mat_re2[BINAURAL_CHANNELS]; + float gd; + float gd2; + int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t gd_idx; + int16_t gd2_idx; + +} ISAR_BIN_HR_SPLIT_REND_MD, *ISAR_BIN_HR_SPLIT_REND_MD_HANDLE; + +typedef struct isar_binaural_head_rot_split_pre_rendering_struct +{ + ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE; + +typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct +{ + void *pLcld_enc; + int16_t iChannels; + LCLDEncoder *psLCLDEncoder; + float ***pppfLCLDReal; + float ***pppfLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbIn; + int16_t numFrame; +#endif + int16_t iNumIterations; + int16_t iNumBlocks; + +} ISAR_BIN_HR_SPLIT_LCLD_ENC, *ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE; + +typedef struct +{ + float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; +} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE; + +typedef struct +{ + ISAR_CLDFB_PLC CldfbPLC_state; + int16_t prev_bfi; + int16_t bf_count; + int16_t iNumSubSets; + +} ISAR_SPLIT_REND_PLC_STRUCT, *ISAR_SPLIT_REND_PLC_HANDLE; + +typedef struct isar_binaural_head_rot_split_rendering_lcld_dec_struct +{ + void *pLcld_dec; + int32_t iChannels; + LCLDDecoder *psLCLDDecoder; + float ***pppfDecLCLDReal; + float ***pppfDecLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbOut; + int16_t numFrame; +#endif + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + int16_t iNumBlocks; + int16_t iNumIterations; + +} ISAR_BIN_HR_SPLIT_LCLD_DEC, *ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE; + +typedef struct isar_binaural_head_rot_split_post_rendering_struct +{ + ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + float mixer_mat_re[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[1][MAX_SPLIT_REND_MD_BANDS]; +#endif + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; +#endif + +} ISAR_BIN_HR_SPLIT_POST_REND, *ISAR_BIN_HR_SPLIT_POST_REND_HANDLE; + +typedef struct +{ + int16_t num_poses; + float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + int16_t dof; + int16_t hq_mode; + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + +} MULTI_BIN_REND_POSE_DATA; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; + int16_t first_good_frame_received; + ISAR_LC3PLUS_DEC_HANDLE hLc3plusDec; + +} ISAR_SPLIT_POST_REND_WRAPPER; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; + CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; + ISAR_LC3PLUS_ENC_HANDLE hLc3plusEnc; + float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + int32_t lc3plusDelaySamples; + +} SPLIT_REND_WRAPPER; + +#endif /* ISAR_STAT_H */ diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..101768bb3468183213a7f80db644c3510499abf9 --- /dev/null +++ b/lib_isar/lib_isar_post_rend.c @@ -0,0 +1,1806 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + + +#include "options.h" +#include "lib_isar_post_rend.h" +#include "isar_prot.h" +#include "prot.h" +#include "ivas_prot.h" + + +#include "ivas_prot_rend.h" +#include +#include +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/* Lightweight helper struct that gathers all information required for rendering + * any config to any other config. Used to simplify signatures of rendering functions. + * + * This struct should store ONLY CONST POINTERS to data existing elsewhere. + * Storing pointers instead of data itself ensures that no additional updates + * are required when any of these are changed in the renderer. Making the pointers + * const ensures that this data is only read, but not modified by the rendering functions. */ +typedef struct +{ + const int32_t *pOutSampleRate; + const AUDIO_CONFIG *pOutConfig; + const ISAR_POST_REND_HeadRotData *pHeadRotData; + const int16_t *pSplitRendBFI; + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig; +} rendering_context_isar; + +/* Common base for input structs */ +typedef struct +{ + AUDIO_CONFIG inConfig; + ISAR_POST_REND_InputId id; + IVAS_REND_AudioBuffer inputBuffer; + float gain; /* Linear, not in dB */ + rendering_context_isar ctx; + int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ +} input_base_isar; + +typedef struct +{ + input_base_isar base; + ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper; + float *bufferData; + int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ + ISAR_POST_REND_BitstreamBuffer *hBits; +} input_split_post_rend; + +struct ISAR_POST_REND +{ + int32_t sampleRateOut; + + IVAS_LIMITER_HANDLE hLimiter; +#ifdef DEBUGGING + int32_t numClipping; /* Counter of clipped output samples */ +#endif + + input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; + + AUDIO_CONFIG inputConfig; + AUDIO_CONFIG outputConfig; + + ISAR_POST_REND_HeadRotData headRotData; + int16_t splitRendBFI; + + int8_t rendererConfigEnabled; + ISAR_SPLIT_REND_CONFIG_DATA splitRenderConfig; + + int16_t num_subframes; +}; + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_AudioConfigType() + * + * + *-------------------------------------------------------------------*/ + +/*! r: ISAR audio type */ +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const AUDIO_CONFIG config /* i : audio configuration */ +) +{ + ISAR_POST_REND_AudioConfigType type; + + switch ( config ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL; + break; + default: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN; + break; + } + + return type; +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error allocateInputBaseBufferData( + float **data, + const int16_t data_size ) +{ + *data = (float *) malloc( data_size * sizeof( float ) ); + if ( *data == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" ); + } + + return IVAS_ERR_OK; +} + + +static void freeInputBaseBufferData( + float **data ) +{ + if ( *data != NULL ) + { + free( *data ); + *data = NULL; + } + + return; +} + + +static IVAS_QUATERNION quaternionInit( + void ) +{ + IVAS_QUATERNION q; + q.w = 1.0f; + q.x = q.y = q.z = 0.0f; + return q; +} + +static void convertBitsBufferToInternalBitsBuff( + const ISAR_POST_REND_BitstreamBuffer outBits, + ISAR_SPLIT_REND_BITS_HANDLE hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; + hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; + hBits->isar_frame_size_ms = outBits.config.isar_frame_size_ms; + hBits->lc3plus_highres = outBits.config.lc3plusHighRes; + + return; +} + + +static void convertInternalBitsBuffToBitsBuffer( + ISAR_POST_REND_BitstreamBuffer *hOutBits, + const ISAR_SPLIT_REND_BITS_DATA bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; + hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; + hOutBits->config.isar_frame_size_ms = bits.isar_frame_size_ms; + hOutBits->config.lc3plusHighRes = bits.lc3plus_highres; + + return; +} + + +static void copyBufferTo2dArray( + const IVAS_REND_AudioBuffer buffer, + float array[][L_FRAME48k] ) +{ + uint32_t smplIdx; + uint32_t chnlIdx; + const float *readPtr; + + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); + readPtr = buffer.data; + + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < (uint32_t) buffer.config.numSamplesPerChannel; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } + + return; +} + + +static void accumulate2dArrayToBuffer( + float array[][L_FRAME48k], + const IVAS_REND_AudioBuffer *buffer ) +{ + int16_t smplIdx, chnlIdx; + float *writePtr; + + writePtr = buffer->data; + for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) + { + *writePtr++ += array[chnlIdx][smplIdx]; + } + } + + return; +} + +#ifndef DISABLE_LIMITER + +/*-------------------------------------------------------------------* + * 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 + if ( output[i] < INT16_MIN || output[i] > INT16_MAX ) + { + ++numClipping; + } +#endif + + output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX ); + } + + return numClipping; +} + +#endif + +/*-------------------------------------------------------------------* + * validateOutputSampleRate() + * + * + *-------------------------------------------------------------------*/ + +static ivas_error validateOutputSampleRate( + const int32_t sampleRate, + const AUDIO_CONFIG outConfig ) +{ + if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } + else + { + /* Otherwise rendering to binaural, support the same set as IVAS decoder */ + switch ( sampleRate ) + { + case 8000: + case 16000: + case 32000: + case 48000: + return IVAS_ERR_OK; + } + + return IVAS_ERR_INVALID_SAMPLING_RATE; + } +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error initLimiter( + IVAS_LIMITER_HANDLE *phLimiter, + const int16_t numChannels, + const int32_t sampleRate ) +{ + ivas_error error; + + /* If re-initializing with unchanged values, return early */ + if ( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate ) + { + return IVAS_ERR_OK; + } + + /* Support re-init: close if already allocated */ + if ( *phLimiter != NULL ) + { + ivas_limiter_close( phLimiter ); + } + + if ( ( error = ivas_limiter_open( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static ivas_error initHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + int16_t i, crossfade_len; + float tmp; + + /* Head rotation is enabled by default */ + hIvasRend->headRotData.headRotEnabled = 1; + + /* Initialize 5ms crossfade */ + crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; + tmp = 1.f / ( crossfade_len - 1 ); + for ( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade[i] = i * tmp; + } + + /* Initialize with unit quaternions */ + for ( i = 0; i < hIvasRend->num_subframes; ++i ) + { + hIvasRend->headRotData.headPositions[i] = quaternionInit(); + } + + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; + + return IVAS_ERR_OK; +} + + +static void initRendInputBase( + input_base_isar *inputBase, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + const rendering_context_isar rendCtx, + float *dataBuf, + const int16_t dataBufSize ) +{ + inputBase->inConfig = inConfig; + inputBase->id = id; + inputBase->gain = 1.0f; + inputBase->ctx = rendCtx; + inputBase->numNewSamplesPerChannel = 0; + + inputBase->inputBuffer.config.numSamplesPerChannel = 0; + inputBase->inputBuffer.config.numChannels = 0; + inputBase->inputBuffer.data = dataBuf; + if ( inputBase->inputBuffer.data != NULL ) + { + set_zero( inputBase->inputBuffer.data, dataBufSize ); + } + + return; +} + + +static rendering_context_isar getRendCtx( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + rendering_context_isar ctx; + + /* Note: when refactoring this, always take the ADDRESS of a member of the + * renderer struct, so that the context stores a POINTER to the member, even + * if the member is a pointer or handle itself. */ + ctx.pOutConfig = &hIvasRend->outputConfig; + ctx.pOutSampleRate = &hIvasRend->sampleRateOut; + ctx.pHeadRotData = &hIvasRend->headRotData; + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; + ctx.pSplitRenderConfig = &hIvasRend->splitRenderConfig; + + return ctx; +} + + +static ivas_error getRendInputNumChannels( + const void *rendInput, + int16_t *numInChannels ) +{ + /* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba). + Assumptions: - input_base_isar is always the first member in the input struct */ + (void) rendInput; + + *numInChannels = 2; + + return IVAS_ERR_OK; +} + + +static ivas_error updateSplitPostRendPanGains( + input_split_post_rend *inputSplitPostRend, + const AUDIO_CONFIG outConfig, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg ) +{ + ivas_error error; + rendering_context_isar rendCtx; + LC3PLUS_CONFIG config; + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + + (void) outConfig; + + rendCtx = inputSplitPostRend->base.ctx; + isar_renderSplitGetMultiBinPoseData( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); + + config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 ); + config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000; + config.isar_frame_duration_us = hRendCfg->isar_frame_size_ms * 1000; + + if ( hRendCfg->codec_frame_size_ms > 0 ) + { + iNumLCLDIterationsPerFrame = (int16_t) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); + iNumBlocksPerFrame = CLDFB_NO_COL_MAX * hRendCfg->codec_frame_size_ms / 20; + } + else + { + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + } + + config.channels = BINAURAL_CHANNELS; + config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate; + + if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + if ( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + if ( ( error = ISAR_LC3PLUS_DEC_Open( config, &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static ivas_error setRendInputActiveSplitPostRend( + void *input, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg ) +{ + ivas_error error; + rendering_context_isar rendCtx; + AUDIO_CONFIG outConfig; + input_split_post_rend *inputSplitPostRend; + + inputSplitPostRend = (input_split_post_rend *) input; + rendCtx = inputSplitPostRend->base.ctx; + outConfig = *rendCtx.pOutConfig; + + if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } + + initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); + inputSplitPostRend->numCachedSamples = 0; + + if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static void clearInputSplitRend( + input_split_post_rend *inputSplitRend ) +{ + rendering_context_isar rendCtx; + + rendCtx = inputSplitRend->base.ctx; + + freeInputBaseBufferData( &inputSplitRend->bufferData ); + + initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + + if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + { + isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); + } + + if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); + } + + if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * ISAR_POST_REND_open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_open( + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t num_subframes /* i : number of subframes */ +) +{ + int16_t i; + ISAR_POST_REND_HANDLE hIvasRend; + ivas_error error; + int16_t numOutChannels; + + (void) asHrtfBinary; + (void) nonDiegeticPan; + (void) nonDiegeticPanGain; + + /* Validate function arguments */ + if ( phIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + *phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) ); + if ( *phIvasRend == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + hIvasRend = *phIvasRend; + hIvasRend->sampleRateOut = outputSampleRate; + hIvasRend->outputConfig = outConfig; + hIvasRend->hLimiter = NULL; + hIvasRend->num_subframes = 1; +#ifdef DEBUGGING + hIvasRend->numClipping = 0; +#endif + hIvasRend->num_subframes = num_subframes; + + /* Initialize limiter */ + if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize headrotation data */ + if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize inputs */ + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + isar_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); + + hIvasRend->splitRendBFI = 0; + hIvasRend->inputsSplitPost[i].bufferData = NULL; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_NumOutChannels() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_NumOutChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *numOutChannels /* o : number of output channels */ +) +{ + /* Validate function arguments */ + if ( hIvasRend == NULL || numOutChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *numOutChannels = 2; + + return IVAS_ERR_OK; +} + + +static IVAS_REND_InputId makeInputId( + AUDIO_CONFIG config, + const int32_t inputIndex ) +{ + /* Put config type in second byte (from LSB), put index + 1 in first byte + * + * Index is incremented here so that a valid ID can never be 0. */ + return (IVAS_REND_InputId) ( ( ( (uint32_t) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); +} + + +static ivas_error getInputById( + ISAR_POST_REND_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + void **ppInput ) +{ + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + input_base_isar *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetInputGain() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetInputGain( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const float gain /* i : linear gain (not in dB) */ +) +{ + input_base_isar *inputBase; + ivas_error error; + + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Hoo\n" ); + return error; + } + + inputBase->gain = gain; + + return IVAS_ERR_OK; +} + + +static ivas_error getConstInputById( + ISAR_POST_REND_CONST_HANDLE hIvasRend, + const ISAR_POST_REND_InputId inputId, + const void **ppInput ) +{ + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + const input_base_isar *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + + +static ivas_error findFreeInputSlot( + const void *inputs, + const int32_t inputStructSize, + const int32_t maxInputs, + int32_t *inputIndex ) +{ + /* Using a void pointer and a separately provided size is a hack for this function + to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). + Assumptions: + - input_base_isar 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_isar *pInputBase; + + canAddInput = false; + + /* Find first unused input in array */ + for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize ) + { + pInputBase = (const input_base_isar *) pByte; + + if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + *inputIndex = i; + canAddInput = true; + break; + } + } + + if ( !canAddInput ) + { + return IVAS_ERR_TOO_MANY_INPUTS; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_AddInput() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +) +{ + ivas_error error; + int32_t maxNumInputsOfType; + void *inputsArray; + int32_t inputStructSize; + + ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA * ); + int32_t inputIndex; + + /* Validate function arguments */ + if ( hIvasRend == NULL || inputId == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + switch ( isar_getAudioConfigType( inConfig ) ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; + inputsArray = hIvasRend->inputsSplitPost; + inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); + activateInput = setRendInputActiveSplitPostRend; + break; + default: + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + + /* Find first free input in array corresponding to input type */ + if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) + { + return error; + } + + *inputId = makeInputId( inConfig, inputIndex ); + + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetInputNumChannels() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetInputNumChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + int16_t *numChannels /* o : number of channels of the input */ +) +{ + ivas_error error; + const input_base_isar *pInput; + + /* Validate function arguments */ + if ( hIvasRend == NULL || numChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetDelay( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */ + int16_t *nSamples, /* o : Renderer delay in samples */ + int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ +) +{ + int16_t i; + int32_t latency_ns; + int32_t max_latency_ns; + + /* Validate function arguments */ + if ( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *timeScale = hIvasRend->sampleRateOut; + *nSamples = 0; + max_latency_ns = 0; + + /* Compute the maximum delay across all inputs */ + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + if ( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + { + latency_ns = 0; + if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) + { + int32_t lc3plusDelaySamples; + ISAR_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); + latency_ns = (int32_t) roundf( lc3plusDelaySamples * 1000000000.f / *timeScale ); + } + if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + max_latency_ns = max( max_latency_ns, latency_ns ); + } + } + + *nSamples = (int16_t) roundf( (float) max_latency_ns * *timeScale / 1000000000.f ); + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_FeedInputAudio() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_FeedInputAudio( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +) +{ + ivas_error error; + input_base_isar *inputBase; + int16_t numInputChannels; + int16_t cldfb2tdSampleFact; + + /* Validate function arguments */ + if ( hIvasRend == NULL || inputAudio.data == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1; + + if ( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); + } + + if ( inputAudio.config.numChannels <= 0 || MAX_INPUT_CHANNELS < inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Foo\n" ); + return error; + } + + if ( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( numInputChannels != inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + inputBase->inputBuffer.config = inputAudio.config; + + mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + + inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_InitConfig() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_InitConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ +) +{ + bool rendererConfigEnabled; + + rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ); + + if ( rendererConfigEnabled ) + { + hIvasRend->rendererConfigEnabled = 1; + } + else + { + hIvasRend->rendererConfigEnabled = 0; + } + + if ( rendererConfigEnabled ) + { + hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k; + hIvasRend->splitRenderConfig.dof = 3; + hIvasRend->splitRenderConfig.hq_mode = 0; + hIvasRend->splitRenderConfig.codec_delay_ms = 0; + hIvasRend->splitRenderConfig.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetRenderConfig() + * + * + *-------------------------------------------------------------------*/ + +int16_t ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +) +{ + ISAR_SPLIT_REND_CONFIG_DATA hRCin; + + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRCin = hIvasRend->splitRenderConfig; + + splitRenderConfig->splitRendBitRate = SPLIT_REND_768k; + splitRenderConfig->dof = 3; + splitRenderConfig->hq_mode = 0; + splitRenderConfig->codec_delay_ms = 0; + splitRenderConfig->codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + splitRenderConfig->isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + splitRenderConfig->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRenderConfig->poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + splitRenderConfig->rendererSelection = hRCin.rendererSelection; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_FeedSplitBinauralBitstream() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +) +{ + ivas_error error; + input_base_isar *inputBase; + input_split_post_rend *inputSplitPostRend; + + /* Validate function arguments */ + if ( hIvasRend == NULL || hBits == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Goo\n" ); + return error; + } + + inputSplitPostRend = (input_split_post_rend *) inputBase; + inputSplitPostRend->hBits = hBits; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetHeadRotation() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const int16_t sf_idx /* i : subframe index */ +) +{ + IVAS_QUATERNION rotQuat; + + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ) + { + /* Head rotation can be set only with binaural output */ + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + hIvasRend->headRotData.headRotEnabled = 1; + + /* check for Euler angle signaling */ + if ( headRot.w == -3.0f ) + { + Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); + } + else + { + rotQuat = headRot; + } + + hIvasRend->headRotData.headPositions[sf_idx] = rotQuat; + hIvasRend->headRotData.Pos[sf_idx] = Pos; + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetSplitRendBFI() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : BFI flag */ +) +{ + hIvasRend->splitRendBFI = bfi; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error splitBinLc3plusDecode( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE bits, + float outputBuffer[BINAURAL_CHANNELS][L_FRAME48k], + const int16_t SplitRendBFI ) +{ + ivas_error error; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + int32_t lc3plusBitstreamSize; + + push_wmops( "splitBinLc3plusDecode" ); + assert( hSplitBin->hLc3plusDec != NULL ); + + for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = outputBuffer[i]; + } + + if ( SplitRendBFI == 0 ) + { + /* Find next byte boundary */ + while ( bits->bits_read % 8 != 0 ) + { + ++bits->bits_read; + } + + /* Size is in bytes */ + assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 ); + lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8; + + if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ISAR_LC3PLUS_DEC_Conceal( hSplitBin->hLc3plusDec, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + pop_wmops(); + return IVAS_ERR_OK; +} + + +static ivas_error renderSplitBinauralWithPostRot( + input_split_post_rend *splitBinInput, + IVAS_REND_AudioBuffer outAudio, + const int16_t SplitRendBFI, + const int16_t num_subframes ) +{ + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + ivas_error error; + float Cldfb_RealBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t sf_idx, ch_idx; + ISAR_SPLIT_REND_BITS_DATA bits; + float tmpCrendBuffer[BINAURAL_CHANNELS][L_FRAME48k]; + float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin; + int8_t isPostRendInputCldfb; + int16_t chnlIdx, slotIdx, smplIdx; + int16_t preRendFrameSize_ms; + int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; + int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; + float *readPtr, *writePtr; + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + const ISAR_POST_REND_HeadRotData *pHeadRotData; + + isPostRendInputCldfb = 0; + push_wmops( "renderSplitBinauralWithPostRot" ); + error = IVAS_ERR_OK; + + if ( outAudio.config.numSamplesPerChannel / *splitBinInput->base.ctx.pOutSampleRate > splitBinInput->hBits->config.isar_frame_size_ms ) + { + return IVAS_ERR_INTERNAL_FATAL; + } + + pHeadRotData = splitBinInput->base.ctx.pHeadRotData; + hSplitBin = &splitBinInput->splitPostRendWrapper; + convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); + + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + if ( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + iNumBlocksPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumBlocks; + iNumLCLDIterationsPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumIterations; + } + + outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / num_subframes; + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx]; + } + + if ( !SplitRendBFI ) + { + hSplitBin->first_good_frame_received = 1; + } + + if ( hSplitBin->first_good_frame_received == 1 ) + { + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( !SplitRendBFI ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); +#else + isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); +#endif + } + } + + /*copy pose correction after MD is parsed*/ + hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; + + /* decode audio */ + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isPostRendInputCldfb = 1; + } + + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel; + + outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; + numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + if ( splitBinInput->numCachedSamples == 0 ) + { + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); + + /* copy data over to 5ms buffer */ + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + { + mvr2r( Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + } + } + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numColPerChannelCacheSize; + writePtr = splitBinInput->bufferData; + for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + } + } + } + else + { + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, SplitRendBFI ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* cache the remaining decoded audio */ + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); + mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); + } + } + else + { + /* copy from cache */ + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); + readPtr = splitBinInput->bufferData; + isPostRendInputCldfb = 1; + + readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + splitBinInput->numCachedSamples -= outBufNumColPerChannel; + } + else + { + int16_t readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples; + mvr2r( splitBinInput->bufferData + readOffset, &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvr2r( splitBinInput->bufferData + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; + } + } + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + if ( splitBinInput->numCachedSamples == 0 ) + { + preRendFrameSize_ms = splitBinInput->base.ctx.pSplitRenderConfig->isar_frame_size_ms; + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); + numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + } + else + { + splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; + } + } + + /* apply pose correction if enabled */ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) + { + /* 0DOF with LCLD codec requires CLDFB synthesis */ + int16_t slot_idx; + + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; + } + + cldfbSynthesis( RealBuffer, + ImagBuffer, + &( tmpCrendBuffer[ch_idx][sf_idx * outBufNumSamplesPerChannel] ), + hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + } + else if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + mvr2r( &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[0], outBufNumSamplesPerChannel ); + mvr2r( &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[1], outBufNumSamplesPerChannel ); + + isar_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb ); + + mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + } + } + } + else + { + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + } + + convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + pop_wmops(); + return error; +} + + +static ivas_error renderInputSplitBin( + input_split_post_rend *splitBinInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio, + const int16_t SplitRendBFI, + const int16_t num_subframes ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = splitBinInput->base.inputBuffer; + + splitBinInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc( inAudio.data, + splitBinInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + switch ( outConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + return error; +} + + +static ivas_error renderActiveInputsSplitBin( + ISAR_POST_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + input_split_post_rend *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_getSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_getSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +) +{ + ivas_error error; + int16_t numOutChannels; + int16_t cldfb2tdSampleFact; + + /* Validate function arguments */ + if ( hIvasRend == NULL || outAudio.data == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1; + + if ( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) + { + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + + if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + /* Clear original output buffer */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + + if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetSplitBinauralSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool *needNewFrame ) +{ + ivas_error error; + + if ( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ +) +{ + uint16_t i; + ISAR_POST_REND_HANDLE hIvasRend; + + /* Validate function arguments */ + if ( phIvasRend == NULL || *phIvasRend == NULL ) + { + return; + } + hIvasRend = *phIvasRend; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); + } + + ivas_limiter_close( &hIvasRend->hLimiter ); + + free( hIvasRend ); + *phIvasRend = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * ISAR_REND_SetSplitRendBitstreamHeader() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_REND_SetSplitRendBitstreamHeader( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o : codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o : pose correction mode */ + const int16_t codec_frame_size_ms, /* i : codec frame size setting */ + const int16_t isar_frame_size_ms, /* i : ISAR codec frame size setting */ + const int16_t lc3plus_highres /* i : LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +) +{ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasRend->splitRenderConfig.codec = codec; + hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms; + hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms; + hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection; + hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres; + + return IVAS_ERR_OK; +} + +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetNoCLipping() + * + * + *-------------------------------------------------------------------*/ + +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + return hIvasRend->numClipping; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetCntFramesLimited() + * + * + *-------------------------------------------------------------------*/ + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + if ( hIvasRend->hLimiter == NULL ) + { + return 0; + } + + return hIvasRend->hLimiter->cnt_frames_limited; +} +#endif diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..ec5b1cc301c059cbcc1bec43e37aa54ff615a5b6 --- /dev/null +++ b/lib_isar/lib_isar_post_rend.h @@ -0,0 +1,219 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef LIB_ISAR_POST_REND_H +#define LIB_ISAR_POST_REND_H + +#include +#include "common_api_types.h" + + +/*---------------------------------------------------------------------* + * ISAR post-renderer constants + *---------------------------------------------------------------------*/ + +#define RENDERER_MAX_ISAR_MD_INPUTS 1 +#define RENDERER_MAX_BIN_INPUTS 1 + +/*---------------------------------------------------------------------* + * ISAR post-renderer structures + *---------------------------------------------------------------------*/ + +typedef struct +{ + int32_t bufLenInBytes; + int32_t bitsWritten; + int32_t bitsRead; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + int16_t codec_frame_size_ms; + int16_t isar_frame_size_ms; + int16_t lc3plusHighRes; +} ISAR_POST_REND_BitstreamBufferConfig; + +typedef struct +{ + ISAR_POST_REND_BitstreamBufferConfig config; + uint8_t *bits; +} ISAR_POST_REND_BitstreamBuffer; + +typedef enum +{ + ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL = 0, + ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN, +} ISAR_POST_REND_AudioConfigType; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + const float *data; +} ISAR_POST_REND_ReadOnlyAudioBuffer; + +typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE; +typedef struct ISAR_POST_REND const *ISAR_POST_REND_CONST_HANDLE; + +typedef uint16_t ISAR_POST_REND_InputId; + +typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL +{ + ISAR_POST_REND_COMPLEXITY_LEVEL_ONE = 1, + ISAR_POST_REND_COMPLEXITY_LEVEL_TWO = 2, + ISAR_POST_REND_COMPLEXITY_LEVEL_THREE = 3 +} ISAR_POST_REND_COMPLEXITY_LEVEL; + + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * ISAR post-renderer function prototypes + *----------------------------------------------------------------------------------*/ + +/* Functions to be called before rendering */ + +ivas_error ISAR_POST_REND_open( + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t num_subframes /* i : number of subframes */ +); + +/* Functions to be called before/during rendering */ + +ivas_error ISAR_POST_REND_NumOutChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *numOutChannels /* o : number of output channels */ +); + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +); + +ivas_error ISAR_POST_REND_SetInputGain( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const float gain /* i : linear gain (not in dB) */ +); + +ivas_error ISAR_POST_REND_GetInputNumChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + int16_t *numChannels /* o : number of channels of the input */ +); + +ivas_error ISAR_POST_REND_GetDelay( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *nSamples, /* o : Renderer delay in samples */ + int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ +); + +/* Functions to be called during rendering */ + +ivas_error ISAR_POST_REND_FeedInputAudio( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +); + +ivas_error ISAR_POST_REND_InitConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ +); + +int16_t ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +); + +ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +); + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool* needNewFrame +); + +ivas_error ISAR_POST_REND_SetHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ + const int16_t sf_idx /* i : subframe index */ +); + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : BFI flag */ +); + + +ivas_error ISAR_POST_REND_getSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +); + +/* Functions to be called after rendering */ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */ +); + +ivas_error ISAR_REND_SetSplitRendBitstreamHeader( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o : codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o : pose correction mode */ + const int16_t codec_frame_size_ms, /* i : codec frame size setting */ + const int16_t isar_frame_size_ms, /* i : ISAR codec frame size setting */ + const int16_t lc3plus_highres /* i : LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +); + +#ifdef DEBUGGING +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ +); + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ +); +#endif + + +/* clang-format on */ + +#endif /* LIB_ISAR_POST_REND_H */ diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..b5090b38c1a06118dccef19ab6f47513d0d2a5aa --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.c @@ -0,0 +1,425 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + + +#include +#include "options.h" +#include +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_cnst.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_PRE_REND_open( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i : IVAS frame size */ + const int16_t mixed_td_cldfb_flag /* i : Flag to indicate combined TD and CLDFB input */ +) +{ + ivas_error error, ch, num_ch; + uint8_t isCldfbNeeded = 0; + int16_t cldfb_in_flag_local = cldfb_in_flag; + + if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), &pSplitRendConfig->isar_frame_size_ms, &pSplitRendConfig->codec_frame_size_ms, cldfb_in_flag_local, pcm_out_flag, (int16_t) ivas_frame_size ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( mixed_td_cldfb_flag ) + { + cldfb_in_flag_local = 0; + } + + if ( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( cldfb_in_flag_local == 0 ) + { + isCldfbNeeded = 1; + } + else if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + else if ( pcm_out_flag && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + + hSplitBinRend->hCldfbHandles = NULL; + + if ( isCldfbNeeded ) + { + if ( ( hSplitBinRend->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + + num_ch = hSplitBinRend->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + if ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData, OutSampleRate ) ) != IVAS_ERR_OK ) +#else + if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + + if ( pcm_out_flag == 0 ) + { + if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs, ivas_frame_size ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + int16_t iNumBlocksPerFrame; + iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; + + if ( ( error = isar_splitBinLCLDEncOpen( &hSplitBinRend->hSplitBinLCLDEnc, output_Fs, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitBinRend->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_close() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_PRE_REND_close( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renderer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ +) +{ + int16_t i; + + if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) + { + isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); + } + + if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + { + isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); + } + + if ( hSplitBinRend->hCldfbHandles != NULL ) + { + int16_t num_ch, ch; + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ); + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + } + + free( hSplitBinRend->hCldfbHandles ); + hSplitBinRend->hCldfbHandles = NULL; + } + + if ( hSplitBinRend->hLc3plusEnc != NULL ) + { + ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers[i] ); + hSplitBinRend->lc3plusDelayBuffers[i] = NULL; + } + } + + if ( pSplitRendEncBuffer != NULL ) + { + + if ( pSplitRendEncBuffer->data != NULL ) + { + free( pSplitRendEncBuffer->data ); + pSplitRendEncBuffer->data = NULL; + } + + pSplitRendEncBuffer->config.numChannels = 0; + pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ISAR_PRE_REND_GetMultiBinPoseData() + * + * + *-------------------------------------------------------------------------*/ + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : Rotation axis */ +) +{ + isar_renderSplitGetMultiBinPoseData( pSplit_rend_config, pMultiBinPoseData, rot_axis ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_MultiBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i : Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ + const int16_t isar_frame_size_ms, /* i : ISAR framesize */ + int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + const int16_t max_bands, /* i : CLDFB bands */ + float *output[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */ +) +{ + ivas_error error; + int32_t bit_len, target_md_bits, available_bits; + + error = IVAS_ERR_OK; + push_wmops( "isar_pre_rend_MultiBinToSplitBinaural" ); + + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData ); + set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); + } + + if ( cldfb_in_flag == 0 ) + { + /*TD input*/ + /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ + error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, isar_frame_size_ms, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag, ro_md_flag ); + + pop_wmops(); + return error; + } + + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + /* Time-align pose correction to delay of LC3plus */ + lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); + } + + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + + + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + } + + if ( pcm_out_flag == 0 ) + { + pBits->codec = splitCodec; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + available_bits -= pBits->bits_written; + pBits->codec_frame_size_ms = codec_frame_size_ms; + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + } + else + { + int16_t ch, slot_idx, num_slots, ivas_fs; + ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; + num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20; + /* CLDFB synthesis of main pose */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; + float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; + Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; + } + + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + } + + if ( pBits->pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + available_bits = isar_get_lc3plus_bitrate( SplitRendBitRate, hSplitBin->multiBinPoseData.poseCorrectionMode, hSplitBin->hLc3plusEnc->config.channels, hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us ) / FRAMES_PER_SEC; + } + else + { + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + } + + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, output ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + int16_t ch, slot_idx; + /* CLDFB synthesis of main pose */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; + float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; + Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; + } + + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + } + + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + if ( pcm_out_flag ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + } + else + { + bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; + bit_len = SplitRendBitRate * bit_len / 1000; + } + } + + while ( pBits->bits_written < bit_len ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + return error; +} diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..02e37dfa48d2122fcc4686f4eb025200d8bd96c7 --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.h @@ -0,0 +1,85 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef LIB_ISAR_PRE_REND_H +#define LIB_ISAR_PRE_REND_H + +#include "isar_stat.h" +#include "isar_prot.h" + + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * ISAR pre-renderer function prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ISAR_PRE_REND_open( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i : IVAS frame size */ + const int16_t mixed_td_cldfb_flag /* i : Flag to indicate combined TD and CLDFB input */ +); + +void ISAR_PRE_REND_close( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renderer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ +); + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : Rotation axis */ +); + +ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i : Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ + const int16_t isar_frame_size_ms, /* i : ISAR framesize */ + int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + const int16_t max_bands, /* i : CLDFB bands */ + float *output[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */ +); + +/* clang-format on */ +#endif /* LIB_ISAR_PRE_REND_H */ diff --git a/lib_lc3plus/.clang-format b/lib_lc3plus/.clang-format index 47a38a93f2dbdd6d944f9dddc3465e3fb65aec29..dc13f4a6e0b377ad4304fbf9e8b45447d859ba3b 100644 --- a/lib_lc3plus/.clang-format +++ b/lib_lc3plus/.clang-format @@ -1,2 +1,3 @@ + DisableFormat: true SortIncludes: Never diff --git a/lib_lc3plus/adjust_global_gain.c b/lib_lc3plus/adjust_global_gain.c index e4ccd48a73dc7076604c0ec4a893b7dc338c2462..d5c122d525bb06ddb3cc68b370f59cd7fa51058f 100644 --- a/lib_lc3plus/adjust_global_gain.c +++ b/lib_lc3plus/adjust_global_gain.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx @@ -18,11 +18,7 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_ LC3_FLOAT delta; LC3_INT delta2; LC3_INT gg_idx_inc; -#ifdef CR8_G_ADD_75MS LC3_FLOAT factor; -#else - LC3_INT factor; -#endif if (frame_dms == 25) { @@ -36,12 +32,10 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_ { factor = 2; } -#ifdef CR8_G_ADD_75MS else if (frame_dms == 75) { factor = 1.2; } -#endif else { factor = 1; diff --git a/lib_lc3plus/al_fec_fl.c b/lib_lc3plus/al_fec_fl.c index dc233ceb289f7c16fac8c795429231f9575de24e..adae19dc394aa7e04cffb95af2257f03433cd073 100644 --- a/lib_lc3plus/al_fec_fl.c +++ b/lib_lc3plus/al_fec_fl.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "stdint.h" #include #include @@ -714,7 +714,6 @@ LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_by if (*bfi == 1) { - return ERROR_REPORT_BEC_MASK; } diff --git a/lib_lc3plus/apply_global_gain.c b/lib_lc3plus/apply_global_gain.c index 43cdcd6facf105aa07423a58d8b99f87273534cb..48305676cd334408aec56e6d22f3a2e493c11dcd 100644 --- a/lib_lc3plus/apply_global_gain.c +++ b/lib_lc3plus/apply_global_gain.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off) diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c index 4ced06e9a10701322c81ec915204cf386c4011ac..5ba87a32bc3b07eeeb825fe2cb6c6271ec9db0a3 100644 --- a/lib_lc3plus/ari_codec.c +++ b/lib_lc3plus/ari_codec.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void ac_shift_fl(Encoder_State_fl* st); @@ -18,105 +18,17 @@ static void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT num static void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side); static LC3_INT sign(LC3_INT x); -#ifdef CR9_SIMPLIFY_ARI_DECODER static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); -#else -static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left); -#endif -#ifdef CR9_SIMPLIFY_ARI_DECODER -static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); -#else static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); -#endif -#ifdef CR9_SIMPLIFY_ARI_DECODER static LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* sym_freq, LC3_INT32 num_sym, LC3_UINT8* ptr, LC3_INT32* bp, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin); -#else -static LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); -#endif -#ifdef CR9_SIMPLIFY_ARI_DECODER static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin); -#else -static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side); -#endif static void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed); static void findNonZero(LC3_INT* in, LC3_INT len, LC3_INT* outLen); -#ifndef CR9_SIMPLIFY_ARI_DECODER -static void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); - -static void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); - -static void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); - -void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; - - *numsym = 18 - 1; - - j = 0; - for (i = 1; i <= *numsym; i++) { - symfreq[j] = ari_spec_cumfreq_fl[pki][i]; - j++; - } - - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_spec_cumfreq_fl[pki][i]; - } - - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_spec_cumfreq_fl[pki][i]; - } -} - -void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; - - *numsym = 18 - 1; - - j = 0; - for (i = 1; i <= *numsym; i++) { - symfreq[j] = ari_tns_freq_cf[k][i]; - j++; - } - - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_tns_freq_cf[k][i]; - } - - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_tns_freq_cf[k][i]; - } -} - -void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; - - *numsym = 8; - - j = 0; - for (i = 1; i < 9; i++) { - symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i]; - j++; - } - - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i]; - } - - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i]; - } -} - -#endif - void findNonZero(LC3_INT* in, LC3_INT len, LC3_INT* outLen) { LC3_INT i = 0, j = 0; @@ -146,7 +58,6 @@ void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed) } } -#ifdef CR9_SIMPLIFY_ARI_DECODER static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin) { LC3_INT32 bp_local, bp_side_local, offset; @@ -240,95 +151,6 @@ static LC3_INT16 pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT3 return 0; } -#else - -static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side) -{ - LC3_INT32 bp_local, bp_side_local, offset; - - if (st_fl->pc_bytes > 0) - { - if (!from_left && mask_side != 1) - { - return; - } - - if (st_fl->pc_c_bp_side > 0 && *bp_side < 0) - { - assert(mask_side == 1); - assert(st_fl->pc_b_right != -1); - *bp_side = st_fl->pc_b_right; - return; - } - - bp_local = *bp; - bp_side_local = *bp_side; - - if (from_left) - { - if (mask_side == 1) - { - bp_side_local = bp_side_local + 1; - } - } else { - bp_local = bp_local - 1; - } - - if (st_fl->pc_b_right == -1) - { - offset = -1; - if (!st_fl->pc_enc) - { - offset = offset + st_fl->pc_bytes; - } - - if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes) - { - st_fl->pc_b_left = bp_local + 1; - st_fl->pc_b_right = bp_side_local - 1; - - if (st_fl->pc_enc) - { - st_fl->pc_return = 1; - return; - } - } - } - - if (!st_fl->pc_enc && st_fl->pc_b_right > -1) - { - if (from_left && *bp == st_fl->pc_b_left) - { - *bp = 0; - st_fl->pc_c_bp = 1; - } - - if (!from_left && bp_side_local == st_fl->pc_b_right) - { - *bp_side = st_fl->pc_bytes - 1; - st_fl->pc_c_bp_side = 1; - } - - if (st_fl->pc_bfi == 2) - { - - if ((st_fl->pc_c_bp && (*bp + 1) >= st_fl->pc_be_bp_left) || (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right)) - { - st_fl->pc_bbi = 2; - } else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1))) - { - st_fl->pc_bbi = 1; - } - } - } - } - - return; -} - -#endif - -#ifdef CR9_SIMPLIFY_ARI_DECODER void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) { LC3_INT i; @@ -354,34 +176,7 @@ void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_IN st_fl->BER_detect = 0; } -#else - -void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) -{ - LC3_INT i = 0; - - if (!st_fl->pc_enc) - { - *bp = *bp + st_fl->pc_bytes; - } - - st_fl->ac_low_fl = 0; - - st_fl->ac_range_fl = (LC3_UINT32)pow(2, 24) - (LC3_UINT32)1; - for (i = 0; i < 3; i++) { - pc_check_bytes(bp, st_fl, from_left, mask_side, bp_side); - - st_fl->ac_low_fl = (st_fl->ac_low_fl << 8) + (LC3_UINT32)ptr[*bp]; - *bp = *bp + 1; - } - - st_fl->BER_detect = 0; -} - -#endif - /* Returns val */ -#ifdef CR9_SIMPLIFY_ARI_DECODER LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 num_sym, LC3_UINT8* ptr, LC3_INT32* bp, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side, LC3_INT16 cur_bin) { LC3_INT val, tmp, symfreq_loc; @@ -427,46 +222,6 @@ LC3_INT32 ac_decode_fl(Decoder_State_fl* st, const LC3_INT16* freq, LC3_INT32 nu return val; } -#else - -LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) -{ - LC3_INT val = 0, tmp = 0; - - - tmp = st->ac_range_fl >> 10; - - if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { - st->BER_detect = 1; - } - - val = num_sym - 1; - - while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) { - val--; - } - - st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val]; - st->ac_range_fl = tmp * sym_freq[val]; - - while (st->ac_range_fl < pow(2, 16)) { - st->ac_low_fl = st->ac_low_fl << 8; - st->ac_low_fl = ((LC3_INT)st->ac_low_fl) & ((LC3_INT)(pow(2, 24) - 1)); - - pc_check_bytes(bp, st, from_left, mask_side, bp_side); - - st->ac_low_fl = st->ac_low_fl + ptr[*bp]; - *bp = *bp + 1; - st->ac_range_fl = st->ac_range_fl << 8; - } - - return val; -} - - -#endif - -#ifdef CR9_SIMPLIFY_ARI_DECODER void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit) { if (ptr[*bp_side] & *mask_side) { @@ -483,33 +238,6 @@ void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* } } -#else - -void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left) -{ - *bit = 0; - - UNUSED(bp); - UNUSED(st_fl); - UNUSED(from_left); - - if (ptr[*bp_side] & *mask_side) { - *bit = 1; - } else { - *bit = 0; - } - - if (*mask_side == 128) { - *mask_side = 1; - *bp_side = *bp_side - 1; - } else { - *mask_side = *mask_side * 2; - } -} - -#endif - -#ifdef CR9_SIMPLIFY_ARI_DECODER void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, @@ -937,550 +665,6 @@ bail: (void)0; } -#else - - -void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, - LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, - LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, - LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms, - LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx, - LC3_INT hrmode -) -{ - Decoder_State_fl st; - LC3_INT a = 0, b = 0, t = 0, bp = 0; - LC3_INT c = 0; - LC3_INT nbits_side = 0, extra_bits = 0; - LC3_UINT8* ptr = NULL; - LC3_INT n = 0, k = 0, lev = 0; - LC3_INT max_lev = 0, tmp = 0; - LC3_INT sym_freq[MAX_LEN] = {0}, cum_freq[MAX_LEN] = {0}, numsym = 0, bit = 0, lev1 = 0, pki = 0, sym = 0, - save_lev[MAX_LEN] = {0}, idx_len = 0, total_bits = 0, nbits_ari = 0, rateFlag = 0; - - total_bits = 8 * numbytes; - - memset(&st, 0, sizeof(st)); - - - st.pc_bytes = (n_pc + 1) >> 1; - st.pc_b_left = numbytes + 1; - st.pc_b_right = -1; - st.pc_enc = enc; - st.pc_bfi = *bfi; - st.pc_be_bp_left = floor(be_bp_left / 8); - st.pc_be_bp_right = floor(be_bp_right / 8) - 1; - *spec_inv_idx = L_spec + 1; - assert(st.pc_be_bp_right < st.pc_bytes || st.pc_bytes == 0); - - /* Rate flag */ - if (fs_idx != 5) - { - if (total_bits > (160 + fs_idx * 160)) { - rateFlag = 512; - } - } - - /* Init */ - c = 0; - t = 0; - bp = 0; - - *b_left = -1; - - ptr = bytes; - - /* Start Decoding */ - ac_dec_init_fl(ptr, &bp, &st, 1, mask_side, &bp_side); - - /* Decode TNS data */ - tmp = MAXLAG; - if (frame_dms == 25) - { - tmp /= 2; - } - if (frame_dms == 50) - { - tmp /= 2; - } - - /* Decode TNS data */ - for (n = 0; n < tns_numfilters; n++) { - - if (tns_order[n] > 0) { - tns_order_freq(enable_lpc_weighting, sym_freq, cum_freq, &numsym); - - tns_order[n] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - tns_order[n] = tns_order[n] + 1; - - if (tns_order[n] > tmp) - { - st.BER_detect = 1; - } - - if (st.pc_bbi == 1) - { - spec_inv_idx = 0; - } else if (st.pc_bbi == 2) - { - st.BER_detect = 1; - } - - for (k = 0; k < tns_order[n]; k++) { - if (bp_side < bp) - { - *bfi = 1; - return; - } - - tns_coef_freq(k, sym_freq, cum_freq, &numsym); - tns_idx[n * 8 + k] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 1) - { - spec_inv_idx = 0; - } else if (st.pc_bbi == 2) - { - st.BER_detect = 1; - } - } - } - } - - if (st.BER_detect > 0) { - *bfi = 1; - return; - } - - /* Spectral data */ - for (k = 0; k < lastnz; k = k + 2) { - /* Context */ - t = c + rateFlag; - - if (k > L_spec / 2) { - t = t + 256; - } - - /* Decode amplitude */ - x[k] = 0; - x[k + 1] = 0; - - if (hrmode == 1) { - max_lev = 13 + 8; - } else { - max_lev = 13; - } - - for (lev = 0; lev <= max_lev; lev++) { - lev1 = MIN(lev, 3); - pki = ari_spec_lookup_fl[t + lev1 * 1024]; - ac_freq(pki, sym_freq, cum_freq, &numsym); - sym = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 1) - { - *spec_inv_idx = MIN(*spec_inv_idx, k); - } else if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - if (sym < 16) { - break; - } - - if (lsbMode == 0 || lev > 0) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - x[k] = x[k] + (bit << lev); - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - x[k + 1] = x[k + 1] + (bit << lev); - } - } - - if ((lev - 1) == 13 && sym == 16) - { - st.BER_detect = 1; - } - - if (hrmode == 0) { - lev = MIN(lev, 13); - } - - if (lsbMode == 1) { - save_lev[k] = lev; - } - - a = sym & 3; - b = sym >> 2; - - x[k] = x[k] + (a << lev); - x[k + 1] = x[k + 1] + (b << lev); - - /* Decode signs */ - if (x[k] > 0) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k; - x[k] = 0; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - if (bit == 1) { - x[k] = -x[k]; - } - } - - if (x[k + 1] > 0) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *spec_inv_idx = k + 1; - x[k + 1] = 0; - calculate_nfseed(x, k, nf_seed); - return; - } - - if (bit == 1) { - x[k + 1] = -x[k + 1]; - } - } - - /* Context */ - lev1 = MIN(lev, 3); - if (lev1 <= 1) { - t = 1 + (a + b) * (lev1 + 1); - } else { - t = 12 + lev1; - } - - c = (c & 15) * 16 + t; - - if (((bp - bp_side) > 3 && (st.pc_c_bp == st.pc_c_bp_side))) { - - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) - { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; - } - - *bfi = 1; - return; - } - - if (st.BER_detect > 0) - { - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) - { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; - } - - *bfi = 1; - return; - } - } - - /* Residual bits */ - nbits_side = total_bits - (8 * bp_side + 8 - (31 - clz_func(mask_side))); - nbits_ari = (bp - 3) * 8; - extra_bits = 25 - (31 - clz_func(st.ac_range_fl)); - - if (enc == 0) - { - if (st.pc_c_bp == 0) - { - nbits_ari = (bp - st.pc_bytes - 3) * 8; - } else { - nbits_ari = (bp + st.pc_b_left - st.pc_bytes - 3) * 8; - } - - if (st.pc_c_bp_side != 0) - { - nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side)); - } - } - - - *nbits_residual = total_bits - (nbits_side + nbits_ari + extra_bits); - - if (*nbits_residual < 0) { - if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) - { - *bfi = 2; - calculate_nfseed(x, k, nf_seed); - return; - } - - *bfi = 1; - return; - } - - if (lsbMode == 0) { - findNonZero(x, L_spec, &idx_len); - if (hrmode) - { - idx_len *= EXT_RES_ITER_MAX; - } - *nbits_residual = MIN(*nbits_residual, idx_len); - *residualPresent = 1; - - memset(resBits, 0, MAX_RESBITS_LEN); - - for (k = 0; k < *nbits_residual; k++) { - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &tmp, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(uint8_t) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - resBits[k >> 3] |= tmp << (k & 7); - } - } else { - for (k = 0; k < lastnz; k = k + 2) { - if (save_lev[k] > 0) { - if (*nbits_residual == 0) { - break; - } - - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; - - if (bit == 1) { - if (x[k] > 0) { - x[k] = x[k] + 1; - } else if (x[k] < 0) { - x[k] = x[k] - 1; - } else { - if (*nbits_residual == 0) { - break; - } - - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; - - if (bit == 0) { - x[k] = 1; - } else { - x[k] = -1; - } - } - } - - if (*nbits_residual == 0) { - break; - } - - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; - - if (bit == 1) { - if (x[k + 1] > 0) { - x[k + 1] = x[k + 1] + 1; - } else if (x[k + 1] < 0) { - x[k + 1] = x[k + 1] - 1; - } else { - if (*nbits_residual == 0) { - break; - } - - pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); - read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); - - if (st.pc_return) - { - *b_left = st.pc_b_left; - return; - } - - if (st.pc_bbi == 2) - { - *bfi = 0; - memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); - calculate_nfseed(x, k, nf_seed); - return; - } - - *nbits_residual = *nbits_residual - 1; - - if (bit == 0) { - x[k + 1] = 1; - } else { - x[k + 1] = -1; - } - } - } - } - } - } - - /* Noise-filling seed */ - calculate_nfseed(x, L_spec, nf_seed); - - /* Zero frame flag */ - if (lastnz == 2 && x[0] == 0 && x[1] == 0 && gg_idx == 0 && fac_ns_idx == 7) { - *zero_frame = 1; - } else { - *zero_frame = 0; - } - - if (enc) - { - if (st.pc_bytes > 0) - { - if (st.pc_b_left > numbytes) - { - *b_left = bp_side - st.pc_bytes; - } - } - } - - if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1))) - { - *bfi = 0; - } - - *spec_inv_idx = *spec_inv_idx - 1; -} - -#endif - void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq) { LC3_INT r; diff --git a/lib_lc3plus/attack_detector.c b/lib_lc3plus/attack_detector.c index ec70b63b67a40882736b075ae25bff6e07720c33..10e3617c8b1e6d53fbde11f5f81143b76aebb486 100644 --- a/lib_lc3plus/attack_detector.c +++ b/lib_lc3plus/attack_detector.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, diff --git a/lib_lc3plus/clib.h b/lib_lc3plus/clib.h index 6588af717d16a41a92d3ca12753528588bb9d4c1..7d2fb7bb10ee010a4abd381340c9a370b0fd5525 100644 --- a/lib_lc3plus/clib.h +++ b/lib_lc3plus/clib.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef CLIB_H #define CLIB_H #include "options.h" +#include "wmc_auto.h" #include #include #include diff --git a/lib_lc3plus/constants.c b/lib_lc3plus/constants.c index 306a8925640108c59b01b3b1e1b77220f3b0d8c0..047b21226d4c1503f1e6735b860c56831dc62a09 100644 --- a/lib_lc3plus/constants.c +++ b/lib_lc3plus/constants.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" /* DCT */ @@ -999,7 +999,6 @@ const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER] = {0, 1, 2, 2, 3, 0}; const LC3_INT BW_cutoff_bin_all_5ms[MAX_BW_BANDS_NUMBER] = {40, 80, 120, 160, 200, 200}; const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER] = {20, 40, 60, 80, 100, 100}; -#ifdef CR8_G_ADD_75MS const LC3_INT BW_cutoff_bin_all_7_5ms[] = {60, 120, 180, 240, 300, 300}; const LC3_INT bands_number_7_5ms_HR [] = {60, 64, 64, 64, 64, 64}; const LC3_INT bands_number_7_5ms [] = {60, 64, 64, 64, 64}; @@ -1022,7 +1021,6 @@ const LC3_INT* BW_warp_idx_start_all_7_5ms[4] = {BW_warp_idx_start_16k_7_5ms, BW BW_warp_idx_start_32k_7_5ms, BW_warp_idx_start_48k_7_5ms}; const LC3_INT* BW_warp_idx_stop_all_7_5ms[4] = {BW_warp_idx_stop_16k_7_5ms, BW_warp_idx_stop_24k_7_5ms, BW_warp_idx_stop_32k_7_5ms, BW_warp_idx_stop_48k_7_5ms}; -#endif /* Arithmetic coding */ const LC3_INT tns_cf[8][18] = {{0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023, 1024}, @@ -1038,9 +1036,6 @@ const LC3_INT tns_freq_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, {0, /* MDCT Windows */ - -#ifdef CR8_G_ADD_75MS - const LC3_FLOAT MDCT_HRA_WINDOW_480_7_5ms[720] = { 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, @@ -3403,7 +3398,6 @@ const LC3_FLOAT MDCT_WINDOW_480_7_5ms[720] = {0.00172152668161197, 0, 0, 0}; -#endif /* #ifdef CR8_G_ADD_75MS */ const LC3_FLOAT MDCT_WINDOW_80_2_5ms[40] = { 6.737914289329320e-03, 2.732289618100209e-02, 6.163560962361236e-02, 1.119125037883055e-01, 1.787053464784875e-01, @@ -5487,12 +5481,10 @@ const LC3_FLOAT* MDCT_WINS_10ms[2][6] = { {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_10ms, MDCT_HRA_WINDOW_960_10ms}}; const LC3_INT MDCT_la_zeroes[6] = {30, 60, 90, 120, 180, 360}; -#ifdef CR8_G_ADD_75MS const LC3_FLOAT* MDCT_WINS_7_5ms[2][6] = { {MDCT_WINDOW_80_7_5ms, MDCT_WINDOW_160_7_5ms, MDCT_WINDOW_240_7_5ms, MDCT_WINDOW_320_7_5ms, MDCT_WINDOW_480_7_5ms, NULL}, {NULL , NULL , NULL , NULL , MDCT_HRA_WINDOW_480_7_5ms, MDCT_HRA_WINDOW_960_7_5ms}}; const LC3_INT32 MDCT_la_zeroes_7_5ms[6] = {14, 28, 42, 56, 84, 168}; -#endif const LC3_FLOAT* MDCT_WINS_2_5ms[2][6] = { {MDCT_WINDOW_80_2_5ms, MDCT_WINDOW_160_2_5ms, MDCT_WINDOW_240_2_5ms, MDCT_WINDOW_320_2_5ms, MDCT_WINDOW_480_2_5ms, @@ -5623,7 +5615,6 @@ const LC3_INT* ACC_COEFF_PER_BAND_5ms[5] = {ACC_COEFF_PER_BAND_8_5ms, ACC_COEFF_ ACC_COEFF_PER_BAND_24_5ms, ACC_COEFF_PER_BAND_32_5ms, ACC_COEFF_PER_BAND_48_5ms}; -#ifdef CR8_G_ADD_75MS const LC3_INT ACC_COEFF_PER_BAND_8_7_5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, @@ -5703,17 +5694,14 @@ const LC3_INT ACC_COEFF_PER_BAND_PLC_96_7_5ms[81] = { const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[] = { ACC_COEFF_PER_BAND_PLC_8_7_5ms, ACC_COEFF_PER_BAND_PLC_16_7_5ms, ACC_COEFF_PER_BAND_PLC_24_7_5ms, ACC_COEFF_PER_BAND_PLC_32_7_5ms, ACC_COEFF_PER_BAND_PLC_48_7_5ms, ACC_COEFF_PER_BAND_PLC_96_7_5ms}; -#endif /* Near Nyquist detector */ const LC3_INT NN_thresh = 30; /* Tone detector */ -#ifdef CR8_E_TONE_DETECTOR const LC3_INT32 TD_HR_thresh_10ms = 83402; const LC3_INT32 TD_HR_thresh_7_5ms = 743496; const LC3_INT32 TD_HR_thresh_5ms = 382564; const LC3_INT32 TD_HR_thresh_2_5ms = 301695; -#endif // CR8_E_TONE_DETECTOR const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; @@ -5721,16 +5709,8 @@ const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; const LC3_INT32 gwlpr[MAX_LGW+1] = { 1, 3*QUOT_LPR_LTR, 5*QUOT_LPR_LTR, 9*QUOT_LPR_LTR, 17*QUOT_LPR_LTR, 33*QUOT_LPR_LTR, 49*QUOT_LPR_LTR, 65*QUOT_LPR_LTR, 81*QUOT_LPR_LTR, 97*QUOT_LPR_LTR}; - -#ifdef CR8_A_PLC_FADEOUT_TUNING /* PLC_FADEOUT_TUNING, extended table ranging from 30 ms to 140 ms */ const LC3_INT16 fade_scheme_tab[24 / 2][3] = { -#if 0 - /* burst_att_thresh indicates when muting POW_ATT_TABLE[att_per_frame_idx] should be used first time it is 1.0 though */ - /* burst_att_thresh ==2 --> gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/ - /* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/ - /* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */ -#endif /* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */ { 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */ { 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */ @@ -5746,17 +5726,9 @@ const LC3_INT16 fade_scheme_tab[24 / 2][3] = { { 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */ }; -#if 0 -/*fade_scheme_tab[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */ -/*fade_scheme_tab[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */ -/*fade_scheme_tab[ind][2] is beta_mute_thr, the location of the start of final muting */ -#endif - - /*compressed ATH Abolute hearing THreshold function weights at band borders */ const LC3_FLOAT scATHFx[MAX_LGW - 2] = { .455444335937500 , 0.930755615234375 , 0.973083496093750 , 0.999969482421875 , 0.908508300781250 , 0.775665283203125 , 0.5 }; -#endif const LC3_FLOAT PhECU_whr16ms_NB[128]={ 8.000000000000002e-02, 8.393536376804722e-02, 9.567411990702857e-02, 1.150154150448081e-01, 1.416283142591582e-01, @@ -6340,7 +6312,7 @@ const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[] = { const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484 }; -#if defined(CR8_A_PLC_FADEOUT_TUNING) const LC3_INT16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200}; const LC3_INT16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7}; -#endif + +const LC3_INT16 PLC_FADEOUT_TYPE_2_SELECTOR = 10; /* can take values from 0 to 10, default is 10 for longer fadeout */ diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h index 6d58a5798addb1c4f07581a6d53d811c08604e40..88d9ed137d7dee795e4393918bc144fad3ebac37 100644 --- a/lib_lc3plus/constants.h +++ b/lib_lc3plus/constants.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef CONSTANTS_H #define CONSTANTS_H #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "structs.h" @@ -113,7 +113,6 @@ extern const LC3_INT bands_number_2_5ms_HR[6]; extern const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER]; extern const LC3_INT bands_number_2_5ms[5]; - extern const LC3_INT BW_warp_idx_start_16k_5ms[4]; extern const LC3_INT BW_warp_idx_stop_16k_5ms[4]; extern const LC3_INT BW_warp_idx_start_24k_5ms[4]; @@ -131,7 +130,6 @@ extern const LC3_INT BW_cutoff_bin_all_5ms_HR[MAX_BW_BANDS_NUMBER]; extern const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER]; extern const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER]; -#ifdef CR8_G_ADD_75MS extern const LC3_INT BW_cutoff_bin_all_7_5ms[MAX_BW_BANDS_NUMBER]; extern const LC3_INT bands_number_7_5ms[6]; extern const LC3_INT bands_number_7_5ms_HR[6]; @@ -139,7 +137,6 @@ extern const LC3_INT* BW_warp_idx_start_all_7_5ms[4]; extern const LC3_INT* BW_warp_idx_stop_all_7_5ms[4]; extern const LC3_INT brickwall_dist_7_5ms[4]; extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[]; -#endif /* Arithmetic coding */ extern const LC3_INT tns_cf[8][18]; @@ -171,10 +168,8 @@ extern const LC3_FLOAT MDCT_WINDOW_480_5ms[480]; extern const LC3_FLOAT* MDCT_WINS_5ms[2][6]; extern const LC3_INT MDCT_la_zeroes_5ms[6]; -#ifdef CR8_G_ADD_75MS extern const LC3_FLOAT* MDCT_WINS_7_5ms[2][6]; extern const LC3_INT32 MDCT_la_zeroes_7_5ms[6]; -#endif extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; extern const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6]; @@ -188,10 +183,8 @@ extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5]; -#ifdef CR8_G_ADD_75MS extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms[5]; -#endif extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; @@ -199,20 +192,16 @@ extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; /* Near Nyquist detector */ extern const LC3_INT NN_thresh; /* Tone detector */ -#ifdef CR8_E_TONE_DETECTOR extern const LC3_INT32 TD_HR_thresh_10ms; extern const LC3_INT32 TD_HR_thresh_7_5ms; extern const LC3_INT32 TD_HR_thresh_5ms; -extern const LC3_INT32 TD_HR_thresh_2_5ms; -#endif // CR8_E_TONE_DETECTOR +extern const LC3_INT32 TD_HR_thresh_2_5ms; extern const LC3_INT32 xavg_N_grp[5]; extern const LC3_FLOAT *hannOla_wins[5]; extern const LC3_INT32 gwlpr[MAX_LGW+1]; -#ifdef CR8_A_PLC_FADEOUT_TUNING extern const LC3_INT16 fade_scheme_tab[24 / 2][3]; extern const LC3_FLOAT scATHFx[MAX_LGW - 2]; -#endif extern const LC3_INT32 mdct_grp_bins[10]; extern const LC3_FLOAT* PhECU_whr16ms_wins[5]; @@ -229,9 +218,7 @@ extern const LC3_FLOAT plc_tdc_lpc_48[17]; extern const LC3_FLOAT plc_tdc_lpc_96[17]; extern const LC3_FLOAT plc_tdc_lpc_8_25ms[9]; -#if defined(CR8_A_PLC_FADEOUT_TUNING) extern const LC3_INT16 plc_fadeout_param_maxlen[4]; extern const LC3_INT16 plc_fadeout_param_maxbytes[4]; -#endif - +extern const LC3_INT16 PLC_FADEOUT_TYPE_2_SELECTOR; #endif /* CONSTANTS_H */ diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c index c2d37312eb17c23d750b816d34a6c46d7cd49888..a2a617bd0daa57c8ced379a607703d8239de111b 100644 --- a/lib_lc3plus/cutoff_bandwidth.c +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c index 9b12627d71e53e585d771098c839cfb87fcf0d5e..4b4a3f6a0f344b45c50624eaf7d59ffe1f26c9fa 100644 --- a/lib_lc3plus/dct4.c +++ b/lib_lc3plus/dct4.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void dct2_init(Dct2* dct, int length) @@ -55,8 +55,8 @@ void dct4_init(Dct4* dct, int length) dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); for (i = 0; i < length / 2; i++) { - dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI * (i + (LC3_FLOAT)0.25) / length); - dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI * i / length); + dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * (i + (LC3_FLOAT)0.25) / length); + dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI_LC3PLUS * i / length); } fft_init(&dct->fft, length / 2); } diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c index f072b82d6f7c62847cdf40d9631654f95df8d63f..cd82570a8181fe6df0b838248b5440fd166cdcac 100644 --- a/lib_lc3plus/dec_entropy.c +++ b/lib_lc3plus/dec_entropy.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c index 7389ffa53e3dd15d57c9ddd55686478bca71c264..f86eff3430dd64fd952c316e0e27aca0da0a8d62 100644 --- a/lib_lc3plus/dec_lc3_fl.c +++ b/lib_lc3plus/dec_lc3_fl.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs_in, void* s_out, int bps, int bfi_ext) { DecSetup* h_DecSetup; @@ -64,11 +63,9 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs case 50: max_bw_stopband = max_bw_stopband >> 1; break; -# ifdef CR8_G_ADD_75MS case 75: max_bw_stopband = 3 * (max_bw_stopband >> 2); break; -# endif case 100: break; } @@ -148,9 +145,7 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs h_DecSetup->PlcSetup.q_d_prev, h_DecSetup->sqQdec_fl, h_DecSetup->spec_inv_idx, decoder->yLen, bfi, decoder->frame_dms, h_DecSetup->concealMethod, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_param[0], &h_DecSetup->PlcAdvSetup->cum_fflcAtten -#ifdef CR8_A_PLC_FADEOUT_TUNING , h_DecSetup->PlcAdvSetup->plc_fadeout_type -#endif ); /* IMDCT */ @@ -171,9 +166,7 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs bfi, h_DecSetup->ltpf_param, h_DecSetup->ltpf_param_mem, h_DecSetup->ltpf_conf_beta_idx, h_DecSetup->ltpf_conf_beta, h_DecSetup->concealMethod, h_DecSetup->alpha , &h_DecSetup->ltpf_mem_active -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH , &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms -#endif ); { @@ -243,7 +236,10 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num } bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, bfi); - input += decoder->channel_setup[ch]->targetBytes; + if (input != NULL) + { + input += decoder->channel_setup[ch]->targetBytes; + } } } else @@ -274,7 +270,11 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num channel_bfi = 1; } - input = input + np_zero; + if (input != NULL) + { + input = input + np_zero; + } + decoder->n_pc = MAX(decoder->n_pc - (2 * np_zero), 0); if (channel_bfi == 2) @@ -312,7 +312,10 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num channel_bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, channel_bfi); out_bfi |= channel_bfi; - input += fec_num_bytes; + if (input != NULL) + { + input += fec_num_bytes; + } } bfi = out_bfi & 1; @@ -359,10 +362,16 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num } bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, bfi); - input += decoder->channel_setup[ch]->targetBytes; + if (input != NULL) + { + input += decoder->channel_setup[ch]->targetBytes; + } } } - if (decoder->last_error == LC3PLUS_OK && bfi) decoder->last_error = LC3PLUS_DECODE_ERROR; + if ((decoder->last_error == LC3PLUS_OK) && bfi) + { + decoder->last_error = LC3PLUS_DECODE_ERROR; + } return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK; } diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h index d9251c018199acd00168afb1398a7782c8c3e3b5..48c89f9ca02b2f2d25701b72b414fe54d168d58c 100644 --- a/lib_lc3plus/defines.h +++ b/lib_lc3plus/defines.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef DEFINES_H #define DEFINES_H #include "options.h" +#include "wmc_auto.h" #include "stdint.h" @@ -25,10 +25,6 @@ typedef int8_t LC3_INT8; typedef uint32_t LC3_UINT32; /* Release defines */ -#define ENABLE_2_5MS_MODE -#define ENABLE_5MS_MODE -#define ENABLE_075_DMS_MODE -#define ENABLE_10_MS_MODE #define ENABLE_ADVANCED_PLC_FL #define ENABLE_ADVANCED_PLC_FL_DEFAULT #define ENABLE_BW_CONTROLLER @@ -43,80 +39,29 @@ typedef uint32_t LC3_UINT32; #define ENABLE_FRAME_MS_FLAG #define ENABLE_HR_MODE_FL_FLAG -#define CR8_G_ADD_75MS - #ifndef NO_POST_REL_CHANGES /* Post-release non-bitexact changes */ -#define CR8_A_PLC_FADEOUT_TUNING /* Adapt PLC fadeout to avoid gaps in signal */ -#define CR9_D_FLOATING_POINT_CODE_SIMPLIFICATIONS -#define CR9_F_PITCH_WIN_LEN_FIX /* Increase window length for pitch calculation */ -#define CR9_G_IMPROVE_TDC /* summarize G,H,J,L,N */ -#ifdef CR9_G_IMPROVE_TDC -# define CR9_G_PLC_NS_TDC_FIX /* Always use TDC if pitch > 0 */ -# define CR9_H_REMOVE_SWITCH_TO_PLC_NS -# define CR9_J_SLOW_TDC_FADEOUT -# define CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER -# ifdef ENABLE_HR_MODE_FL -# ifdef PLC_TUNING_SHORT_FADEOUT -# define CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH -# endif -# endif -#endif /* CR9_G_IMPROVE_TDC */ -#define CR9_I_INC_TDC_FADEOUT_LEN -#define CR9_K_REDUCE_NORM_CORR_TH #endif /* NO_POST_REL_CHANGES */ -#ifdef CR9_D_FLOATING_POINT_CODE_SIMPLIFICATIONS -# define CR9_SIMPLIFY_LOOP -# define CR9_LTPF_REWRITE -# define CR9_QUANT_SPEC_REWRITE -# define CR9_SIMPLIFY_ARI_DECODER -#endif - -#ifdef CR8_A_PLC_FADEOUT_TUNING #define MAX_UINT8 255 -# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER -# ifdef CR9_K_REDUCE_NORM_CORR_TH -# define THRESH_100_DMS_TDC_CNT 9 -# define THRESH_100_DMS_NS_CNT 7 -# define THRESH_100_DMS_TDC_NS_CNT 73 -# define THRESH_075_DMS_TDC_CNT 7 -# define THRESH_075_DMS_NS_CNT 7 -# define THRESH_075_DMS_TDC_NS_CNT 87 -# define THRESH_050_DMS_TDC_CNT 22 -# define THRESH_050_DMS_NS_CNT 15 -# define THRESH_050_DMS_TDC_NS_CNT 141 -# define THRESH_025_DMS_TDC_CNT 20 -# define THRESH_025_DMS_NS_CNT 21 -# define THRESH_025_DMS_TDC_NS_CNT 278 -# else -# define THRESH_100_DMS_TDC_CNT 3 -# define THRESH_100_DMS_NS_CNT 35 -# define THRESH_100_DMS_TDC_NS_CNT 114 -# define THRESH_075_DMS_TDC_CNT 6 -# define THRESH_075_DMS_NS_CNT 37 -# define THRESH_075_DMS_TDC_NS_CNT 130 -# define THRESH_050_DMS_TDC_CNT 12 -# define THRESH_050_DMS_NS_CNT 55 -# define THRESH_050_DMS_TDC_NS_CNT 227 -# define THRESH_025_DMS_TDC_CNT 10 -# define THRESH_025_DMS_NS_CNT 138 -# define THRESH_025_DMS_TDC_NS_CNT 431 -# endif -# else -# define FAC1_FADEOUT 0.2 -# define FAC2_FADEOUT 1.5 -# define FAC3_FADEOUT 1.75 -# endif +#define THRESH_100_DMS_TDC_CNT 9 +#define THRESH_100_DMS_NS_CNT 7 +#define THRESH_100_DMS_TDC_NS_CNT 73 +#define THRESH_075_DMS_TDC_CNT 7 +#define THRESH_075_DMS_NS_CNT 7 +#define THRESH_075_DMS_TDC_NS_CNT 87 +#define THRESH_050_DMS_TDC_CNT 22 +#define THRESH_050_DMS_NS_CNT 15 +#define THRESH_050_DMS_TDC_NS_CNT 141 +#define THRESH_025_DMS_TDC_CNT 20 +#define THRESH_025_DMS_NS_CNT 21 +#define THRESH_025_DMS_TDC_NS_CNT 278 #define REL_PITCH_THRESH 0.36 #define PLC_LONGTERM_ANALYSIS_MS 200 /* Analysis window 2000 ms / 10 ms */ #define PLC_LONGTERM_ANALYSIS_STARTUP_FILL 0.5f /* required buffer fill amount, set to 0.0 to not require any fill at all */ - -#endif - /* Precision Defines */ #define LC3_FABS(x) (fabsf(x)) #define LC3_POW(x, y) (powf(x, y)) @@ -127,109 +72,91 @@ typedef uint32_t LC3_UINT32; #define LC3_SQRT(x) (sqrtf(x)) #define LC3_EXP(x) (expf(x)) -# define MAX_BR 320000 /* 400 * 800 */ -# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ -# define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */ -# define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ -# define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ -# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ -# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ -# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ - -#ifdef CR8_G_ADD_75MS -# define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800 -# define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800 -# define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */ -# define MAX_BR_075DMS 426667 /* ceil(400 * 800 * 100/ 75) */ -# define MAX_BR_075DMS_NB 152534 /* ceil(143 * 800 * 100/ 75) */ -# define MAX_BR_075DMS_WB 295467 /* ceil(277 * 800 * 100/ 75) */ -# define MAX_BR_075DMS_SSWB 419200 /* ceil(393 * 800 * 100/ 75) */ -#endif -# define CR8_E_TONE_DETECTOR /* Tone detector for hrmode to deactivate TNS - improves SNR and THD+N */ - +#define MAX_BR 320000 /* 400 * 800 */ +#define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ +#define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */ +#define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ +#define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ +#define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ +#define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ +#define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ + +#define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800 +#define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800 +#define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */ +#define MAX_BR_075DMS 426667 /* ceil(400 * 800 * 100/ 75) */ +#define MAX_BR_075DMS_NB 152534 /* ceil(143 * 800 * 100/ 75) */ +#define MAX_BR_075DMS_WB 295467 /* ceil(277 * 800 * 100/ 75) */ +#define MAX_BR_075DMS_SSWB 419200 /* ceil(393 * 800 * 100/ 75) */ typedef int32_t LC3_INT32; -# if defined(__xtensa__) -# define ALIGNMENT_BALLOC 4 -# define ALIGNMENT_BALLOC_RED 3 -# else -# define ALIGNMENT_BALLOC 8 -# define ALIGNMENT_BALLOC_RED 7 -# endif - -#ifndef CR8_A_PLC_FADEOUT_TUNING -# define PLC2_FADEOUT_IN_MS 30 +#if defined(__xtensa__) +#define ALIGNMENT_BALLOC 4 +#define ALIGNMENT_BALLOC_RED 3 +#else +#define ALIGNMENT_BALLOC 8 +#define ALIGNMENT_BALLOC_RED 7 #endif -#ifdef CR8_A_PLC_FADEOUT_TUNING /* PLC2/PhEcu fading settings */ /* PLC2/PHEcu muting Table setup settings */ -# define PLC2_FADEOUT_IN_MS_MIN 30 /* Table min */ -# define PLC2_FADEOUT_IN_MS_MAX 140 /* Table max */ -# define PLC2_FADEOUT_RES 10 /* 10 ms steps used in fadeout constant tables */ +#define PLC2_FADEOUT_IN_MS_MIN 30 /* Table min */ +#define PLC2_FADEOUT_IN_MS_MAX 140 /* Table max */ +#define PLC2_FADEOUT_RES 10 /* 10 ms steps used in fadeout constant tables */ /* current active settings */ -# define PLC2_FADEOUT_IN_MS 30 /* 30 P800 fadeout optimized */ -#if 0 -# define PLC2_FADEOUT_LONG_IN_MS 50 /* 50 ABBA test */ -#endif -# define PLC2_FADEOUT_LONG_IN_MS 120 /* 120 MUSHRA, && stable tonal fadeout optimized */ - -#endif - -# define PHECU_FRES 62.5 -# define PHECU_C_JACOB 1.1429 -# define MAX_LGW 9 /* LGW48K + 1 !! */ -# define QUOT_LPR_LTR 4 -# define MAX_PLC_LPROT ((512 * 48) / 32) -# define MAX_PLC_NPLOCS ((MAX_PLC_LPROT / 4) + 1) -# define MAX_PLC_LMSPEC ((MAX_PLC_LPROT / 2) + 1) -# define MAX_PLC_LMEM (400) /* "only" up to 20kHz (400 MDCT bins at 10 ms) at 48 kHz supported by PhEcu */ - -# define POS_ONE_Q15 (32767.0 / 32768.0) -# define PHECU_LTOT_MIN_MAN 1 /* lowest possible mantissa energy value */ -# define PHECU_LTOT_MIN_EXP -61 /* L_tot = PHECU_LTOT_MIN_MAN*2^(PHECU_LTOT_MIN_EXP-31) */ -# define PHECU_LTOT_MIN -# define PHECU_GRP_SHAPE_INIT 0 /* BASOP Q15 */ -# define PHECU_ENV_STAB_LOCAL POS_ONE_Q15 -# define PHECU_DELTA_CORR 5 -# define PHECU_PFIND_SENS 0.93 -# define PHECU_LA 0 - -# define LC3_ROUND(x) (roundf(x)) -# define LC3_FLOOR(x) (floorf(x)) - -# define LC3_CONST_POW_2_16 65536 -# define LC3_CONST_POW_2_M16 1.525878906250000e-05 -# define LC3_CONST_POW_2_100 1.267650600228229e+30 - -# define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN) -# define MAX_PITCH CEILING((MAX_PITCH_12K8 * MAX_LEN * 100), 12800) -# define TDC_L_FIR_HP 11 -# define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ - -#ifdef CR9_I_INC_TDC_FADEOUT_LEN -# define PLC_FADEOUT_TYPE_1_IN_MS 200 -#endif -# define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */ -# define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ -# define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ -# define PLC34_ATTEN_FAC_100 0.5000 /* attenuation factor for NS and TDC @ 10 ms*/ -#ifdef CR8_G_ADD_75MS -# define PLC34_ATTEN_FAC_075 0.5946 /* attenuation factor for NS and TDC @ 7.5 ms */ -#endif -# define PLC34_ATTEN_FAC_050 0.7071 /* attenuation factor for NS and TDC @ 5.0 ms*/ -# define PLC34_ATTEN_FAC_025 0.8409 /* attenuation factor for NS and TDC @ 2.5 ms*/ - -# define FEC_SLOT_BYTES_MIN 40 -# define FEC_SLOT_BYTES_MAX 400 - -# define LC3_CONST_POW_2_M15 3.051757812500000e-05 -# define LC3_CONST_POW_2_23 8388608 -# define LC3_CONST_POW_2_23_NEG -8388608 -# define LC3_CONST_POW_2_23_RED 8388607 - -# define LC3_CONST_POW_2_100 1.267650600228229e+30 +#define PLC2_FADEOUT_IN_MS 30 /* 30 P800 fadeout optimized */ +#define PLC2_FADEOUT_LONG_IN_MS 120 /* 120 MUSHRA, && stable tonal fadeout optimized */ + +#define PHECU_FRES 62.5 +#define PHECU_C_JACOB 1.1429 +#define MAX_LGW 9 /* LGW48K + 1 !! */ +#define QUOT_LPR_LTR 4 +#define MAX_PLC_LPROT ((512 * 48) / 32) +#define MAX_PLC_NPLOCS ((MAX_PLC_LPROT / 4) + 1) +#define MAX_PLC_LMSPEC ((MAX_PLC_LPROT / 2) + 1) +#define MAX_PLC_LMEM (400) /* "only" up to 20kHz (400 MDCT bins at 10 ms) at 48 kHz supported by PhEcu */ + +#define POS_ONE_Q15 (32767.0 / 32768.0) +#define PHECU_LTOT_MIN_MAN 1 /* lowest possible mantissa energy value */ +#define PHECU_LTOT_MIN_EXP -61 /* L_tot = PHECU_LTOT_MIN_MAN*2^(PHECU_LTOT_MIN_EXP-31) */ +#define PHECU_LTOT_MIN +#define PHECU_GRP_SHAPE_INIT 0 /* BASOP Q15 */ +#define PHECU_ENV_STAB_LOCAL POS_ONE_Q15 +#define PHECU_DELTA_CORR 5 +#define PHECU_PFIND_SENS 0.93 +#define PHECU_LA 0 + +#define LC3_ROUND(x) (roundf(x)) +#define LC3_FLOOR(x) (floorf(x)) + +#define LC3_CONST_POW_2_16 65536 +#define LC3_CONST_POW_2_M16 1.525878906250000e-05 +#define LC3_CONST_POW_2_100 1.267650600228229e+30 + +#define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN) +#define MAX_PITCH CEILING((MAX_PITCH_12K8 * MAX_LEN * 100), 12800) +#define TDC_L_FIR_HP 11 +#define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ + +#define PLC_FADEOUT_TYPE_1_IN_MS 200 +#define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */ +#define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ +#define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ +#define PLC34_ATTEN_FAC_100 0.5000 /* attenuation factor for NS and TDC @ 10 ms*/ +#define PLC34_ATTEN_FAC_075 0.5946 /* attenuation factor for NS and TDC @ 7.5 ms */ +#define PLC34_ATTEN_FAC_050 0.7071 /* attenuation factor for NS and TDC @ 5.0 ms*/ +#define PLC34_ATTEN_FAC_025 0.8409 /* attenuation factor for NS and TDC @ 2.5 ms*/ + +#define FEC_SLOT_BYTES_MIN 40 +#define FEC_SLOT_BYTES_MAX 400 + +#define LC3_CONST_POW_2_M15 3.051757812500000e-05 +#define LC3_CONST_POW_2_23 8388608 +#define LC3_CONST_POW_2_23_NEG -8388608 +#define LC3_CONST_POW_2_23_RED 8388607 + +#define LC3_CONST_POW_2_100 1.267650600228229e+30 /* G192 bitstream writing/reading */ #define G192_REDUNDANCY_FRAME 0x6B22 @@ -241,28 +168,20 @@ typedef int32_t LC3_INT32; #ifdef DEBUG #ifdef READ_G192FER -# define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */ +#define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */ #endif #endif -# define LC3_EPS (1.1e-7f) +#define LC3_EPS (1.1e-7f) -#define M_PI 3.14159265358979323846 +#define M_PI_LC3PLUS 3.14159265358979323846 /* FUNCTION MACROS */ #define CEILING(x, y) (((x) + (y)-1) / (y)) - - -#ifdef CR8_A_PLC_FADEOUT_TUNING #define FRAME2FS_IDX_10MS(x) (x<500 ? (x/100) : 5) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4 , 960 -> 5*/ #define FS2FS_IDX(x) ((x) == 96000 ? 5 : (x) / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4, 96000 -> 5 */ -#else -#define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4*/ -#define FS2FS_IDX(x) \ - (x / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4 \ - */ -#endif + #define UNUSED(x) (void)(x) /* silence unused parameter warning */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -273,7 +192,7 @@ typedef int32_t LC3_INT32; /* For dynamic memory calculations */ #define CODEC_FS(fs) ((fs) == 44100 ? 48000 : (fs)) #define DYN_MAX_LEN(fs) MAX(CODEC_FS(fs) / 100, 160) -# define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */ +#define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */ #define DYN_MAX_MDCT_LEN(fs) (DYN_MAX_LEN(fs) - (180 * DYN_MAX_LEN(fs) / 480)) /* OPTIONS */ @@ -295,25 +214,25 @@ typedef int32_t LC3_INT32; #define MAX_NBYTES_100 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ #ifdef ENABLE_HR_MODE_FL -# define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200 -# define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200 -# define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600 -# define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600 -# define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800 -# define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800 +#define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200 +#define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200 +#define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600 +#define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600 +#define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800 +#define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800 #endif /* ENABLE_HR_MODE */ #define MAX_NBYTES2 625 #define BYTESBUFSIZE (MAX_NBYTES2 * MAX_CHANNELS) #define MAX_BW_BIN 400 #if MAX_BW_BIN > MAX_LEN -# define MAX_BW MAX_LEN +#define MAX_BW MAX_LEN #else -# define MAX_BW MAX_BW_BIN +#define MAX_BW MAX_BW_BIN #endif -# ifdef ENABLE_HR_MODE_FL -# define MAX_BW_HR 960 -# endif +#ifdef ENABLE_HR_MODE_FL +#define MAX_BW_HR 960 +#endif /* SCF */ #define M 16 diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c index 239da4255fcfb10335c7505711c5cdcbf1845296..4005c68e74446270079ca0028b4c41d5fda2a5ee 100644 --- a/lib_lc3plus/detect_cutoff_warped.c +++ b/lib_lc3plus/detect_cutoff_warped.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) @@ -33,13 +33,11 @@ void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_d warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; bw_dist = brickwall_dist; break; -#ifdef CR8_G_ADD_75MS case 75: warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1]; warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1]; bw_dist = brickwall_dist_7_5ms; break; -#endif case 100: warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c index 23423b5d809734869c165e9fdd62e1fed9ab68ad..28e3cea69cde99ee361c6d6701aca9556ec09866 100644 --- a/lib_lc3plus/enc_entropy.c +++ b/lib_lc3plus/enc_entropy.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static const LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c index 404b80fb4b10fbb313bbc5d286048728e0bee509..0729df98dcdff9450f4ab2a418f055eb2d940a31 100644 --- a/lib_lc3plus/enc_lc3_fl.c +++ b/lib_lc3plus/enc_lc3_fl.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - - + #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps @@ -63,9 +63,7 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s /* Pitch estimation */ processOlpa_fl(h_EncSetup->s_12k8, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, &h_EncSetup->olpa_mem_pitch, -#ifdef CR9_F_PITCH_WIN_LEN_FIX &h_EncSetup->pitch_flag, -#endif &T0_out, &normcorr, s_12k8_len, encoder->frame_dms); /* LTPF encoder */ @@ -74,9 +72,7 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_ltpf_on, &h_EncSetup->ltpf_mem_pitch, h_EncSetup->ltpf_param, &h_EncSetup->ltpf_mem_mem_normcorr, <pfBits -#ifdef CR9_K_REDUCE_NORM_CORR_TH - ,encoder->hrmode -#endif + , encoder->hrmode ); /* Attack detector */ @@ -87,12 +83,8 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s /* Per-band energy */ processPerBandEnergy_fl(encoder->bands_number, encoder->bands_offset, encoder->hrmode, encoder->frame_dms, h_EncSetup->ener, d_fl); /* Near Nyquist detector */ - processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener -#ifdef CR8_E_TONE_DETECTOR - , encoder->frame_dms, encoder->hrmode ); -#else - ); -#endif + processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener + , encoder->frame_dms, encoder->hrmode ); /* Disable LTPF if nyquist detector triggers or -lfe mode is active*/ if (encoder->near_nyquist_flag != 0 || h_EncSetup->lfe == 1) { diff --git a/lib_lc3plus/estimate_global_gain.c b/lib_lc3plus/estimate_global_gain.c index fdaa977c0644c7d72e4949d298cd2ce835160868..c32d85c363016cb28552f0f71f101e81728add55 100644 --- a/lib_lc3plus/estimate_global_gain.c +++ b/lib_lc3plus/estimate_global_gain.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/fft/cfft.c b/lib_lc3plus/fft/cfft.c index e8a6304ee17ec78ed1fc056c3af0628b6e23b84f..6ec89eb2992142e6899c773ddd43f8d5a6464907 100644 --- a/lib_lc3plus/fft/cfft.c +++ b/lib_lc3plus/fft/cfft.c @@ -1,15 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - - #include "options.h" +#include "wmc_auto.h" #include "cfft.h" #include "iisfft.h" /* for M_PIl */ #include /* for abs() */ @@ -386,8 +385,10 @@ void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT length, LC3_INT stride, LC3_ LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign) { /* check if length is power of two */ - if (!CFFT_PLAN_SUPPORT(length) || abs(sign) != 1) + if (!CFFT_PLAN_SUPPORT(length) || (abs(sign) != 1)) + { return 0; + } handle->len = length; handle->sign = sign; @@ -418,5 +419,7 @@ void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride) void LC3_cfft_free(Cfft* handle) { if (handle->table) + { free(handle->table); + } } diff --git a/lib_lc3plus/fft/cfft.h b/lib_lc3plus/fft/cfft.h index 6ba8dfccd372823a10726793c87d8daa652b90dd..a67d66f057aec75a329745723c6814139e4829dc 100644 --- a/lib_lc3plus/fft/cfft.h +++ b/lib_lc3plus/fft/cfft.h @@ -1,15 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - - #include "options.h" +#include "wmc_auto.h" #include "../functions.h" #ifndef CFFT_H diff --git a/lib_lc3plus/fft/fft_15_16.h b/lib_lc3plus/fft/fft_15_16.h index c527f1bf5625413c85da3c5f7026f8ed71f66ea2..ced87c6671b6f664a8fae68bcf8be9b70139da70 100644 --- a/lib_lc3plus/fft/fft_15_16.h +++ b/lib_lc3plus/fft/fft_15_16.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/fft_240_480.h b/lib_lc3plus/fft/fft_240_480.h index 18a0c8707a871b091ff60d0f59262e500d89ff9f..40969ba48e88a749e56070a3612410d16cd5701f 100644 --- a/lib_lc3plus/fft/fft_240_480.h +++ b/lib_lc3plus/fft/fft_240_480.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/fft_2_9.h b/lib_lc3plus/fft/fft_2_9.h index 55fe84f3b779057b5c65c63587b262cf20b7cf15..0166ad43d75abbbf681199818925b5e150fc01d0 100644 --- a/lib_lc3plus/fft/fft_2_9.h +++ b/lib_lc3plus/fft/fft_2_9.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/fft_32.h b/lib_lc3plus/fft/fft_32.h index 803923a0158c42dc3f0d88ae81cb5765e6acf8a5..39cffc69775ca21ee2c2514ceb19932a2a01db2f 100644 --- a/lib_lc3plus/fft/fft_32.h +++ b/lib_lc3plus/fft/fft_32.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/fft_384_768.h b/lib_lc3plus/fft/fft_384_768.h index bd89393c174c8f14b4b2db5fee253f0a41e803c8..404ef79492e9b1879da06eabb893b5d0c5d590ec 100644 --- a/lib_lc3plus/fft/fft_384_768.h +++ b/lib_lc3plus/fft/fft_384_768.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/fft_60_128.h b/lib_lc3plus/fft/fft_60_128.h index e5a88ccad873d19fb1757cc14df1be36d6502b50..e2b17450e7b6d69ce36edf5b14f7416d89e2f698 100644 --- a/lib_lc3plus/fft/fft_60_128.h +++ b/lib_lc3plus/fft/fft_60_128.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/fft_generic.h b/lib_lc3plus/fft/fft_generic.h index 903875ab5a7b6ef471e4898ca3a868d49bebeb67..32030b5ca413f20dccf0b3811d68ce9b9c865d2a 100644 --- a/lib_lc3plus/fft/fft_generic.h +++ b/lib_lc3plus/fft/fft_generic.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /* guard against unindended includes */ #ifndef INCLUDED_FROM_IISFFT_C diff --git a/lib_lc3plus/fft/iis_fft.c b/lib_lc3plus/fft/iis_fft.c index 30ae240200b48660d57df9a92d490f301551c2ab..085e60635cf83bdd559028b5a636958cbb8b1a03 100644 --- a/lib_lc3plus/fft/iis_fft.c +++ b/lib_lc3plus/fft/iis_fft.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include #include #include @@ -37,14 +37,20 @@ static IIS_FFT_ERROR create(HANDLE_IIS_FFT* handle, LC3_INT type, LC3_INT len, I LC3_INT trlen = (type == FFT_COMPLEX) ? len : len / 2; /* check argument sanity */ - if (sign != IIS_FFT_FWD && sign != IIS_FFT_BWD) + if ((sign != IIS_FFT_FWD) && (sign != IIS_FFT_BWD)) + { return IIS_FFT_INTERNAL_ERROR; + } if (!(*handle)) + { (*handle) = (HANDLE_IIS_FFT)calloc(1, sizeof(IIS_FFT)); + } if (!(*handle)) + { return IIS_FFT_MEMORY_ERROR; + } (*handle)->len = len; (*handle)->sign = sign; @@ -121,7 +127,9 @@ IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input { LC3_FLOAT* dummy; if (!handle) + { return IIS_FFT_INTERNAL_ERROR; + } /* check for inplace operation */ memmove(output, input, sizeof(*input) * handle->len); diff --git a/lib_lc3plus/fft/iis_fft.h b/lib_lc3plus/fft/iis_fft.h index b70a3719d3d671c8e47f4191955fbe78ae8076a0..d68b27d8911a5816fd78cb039f4ca9e063002f48 100644 --- a/lib_lc3plus/fft/iis_fft.h +++ b/lib_lc3plus/fft/iis_fft.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef IIS_FFT_H #define IIS_FFT_H #include "options.h" +#include "wmc_auto.h" #include "../structs.h" #include "../defines.h" #include "cfft.h" diff --git a/lib_lc3plus/fft/iisfft.c b/lib_lc3plus/fft/iisfft.c index cdf7f8d2a8faf2d494a4693eba9cbc0682fb786f..aaca87db9f07b92d05d33d03b2ae90612afd8ac1 100644 --- a/lib_lc3plus/fft/iisfft.c +++ b/lib_lc3plus/fft/iisfft.c @@ -1,15 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - - #include "options.h" +#include "wmc_auto.h" #include #include /* for mmove */ #include @@ -60,7 +59,9 @@ IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) { memset(handle, 0, sizeof(Iisfft)); if (length < 2) + { return IIS_FFT_LENGTH_ERROR; + } handle->length = length; handle->sign = sign; if (need_scratch(length)) { @@ -68,7 +69,9 @@ IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) LC3_INT i = 0; LC3_INT lengthOfPrimeScratch = BORDER_FOR_SECOND_SCRATCH; if (!factorize(length, &handle->num_factors, handle->factors, handle->isPrime)) + { return IIS_FFT_LENGTH_ERROR; + } /* create additional scratch for primeFFT() */ for (i = 0; i < handle->num_factors; i++) { if (handle->isPrime[i] == 1 && handle->factors[i] > lengthOfPrimeScratch) { @@ -78,7 +81,9 @@ IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) if (lengthOfPrimeScratch > BORDER_FOR_SECOND_SCRATCH) { handle->scratch2 = (LC3_INT*)malloc(sizeof(LC3_INT) * lengthOfPrimeScratch); if (!handle->scratch2) + { return IIS_FFT_MEMORY_ERROR; + } } } @@ -89,7 +94,9 @@ void LC3_iisfft_free(Iisfft* handle) { handle->length = 0; if (handle->scratch2) + { free(handle->scratch2); + } } diff --git a/lib_lc3plus/fft/iisfft.h b/lib_lc3plus/fft/iisfft.h index b45e73cdec772d0f494ba1d45c79b75cf2e1e82b..4fe8f3abc3490ce2327ea8efc48ffab515746906 100644 --- a/lib_lc3plus/fft/iisfft.h +++ b/lib_lc3plus/fft/iisfft.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef IISFFT_H #define IISFFT_H #include "options.h" +#include "wmc_auto.h" #include "../defines.h" #ifndef M_PIl diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h index b0997e85fac8d5e7973c498885bfab736bead53c..46daa64bf3f3757f8f546a4c2d5c878a7924eb2b 100644 --- a/lib_lc3plus/functions.h +++ b/lib_lc3plus/functions.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef FUNCTIONS_H #define FUNCTIONS_H #include "options.h" +#include "wmc_auto.h" #include "clib.h" #include "defines.h" #include "float.h" @@ -108,9 +108,7 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3 void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx); void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, -#ifdef CR9_F_PITCH_WIN_LEN_FIX LC3_INT* pitch_flag, -#endif LC3_INT* T0_out,LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms); void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, @@ -127,12 +125,8 @@ void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx); void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener -#ifdef CR8_E_TONE_DETECTOR - , const LC3_INT16 frame_dms, const LC3_INT16 hrmode ); -#else - ); -#endif + const LC3_INT bands_number, const LC3_FLOAT* ener + , const LC3_INT16 frame_dms, const LC3_INT16 hrmode ); void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d); void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, @@ -143,18 +137,14 @@ void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits -#ifdef CR9_K_REDUCE_NORM_CORR_TH - ,LC3_INT16 hrmode -#endif + , LC3_INT16 hrmode ); void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, LC3_INT* mem_pitch_LC3_INT, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping , LC3_INT *mem_ltpf_active -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms -#endif ); void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], @@ -241,17 +231,13 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, LC3_FLOAT *cum_fflcAtten -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ); void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ); void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len, @@ -278,10 +264,8 @@ void plc_phEcu_spec_ana(LC3_FLOAT* xfp, LC3_INT32 xfp_len, const LC3_FLOAT* void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT16 fadeout, /* needed for DC muting */ LC3_INT16* nonpure_tone_flag_ptr, /* i/o: flag */ -#endif LC3_FLOAT *corr_phase_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg); void plc_phEcu_rec_frame(Complex *X_in, LC3_INT32 xfp_len, LC3_INT32 Lecu, const LC3_FLOAT *whr, const LC3_FLOAT *winMDCT, LC3_INT32 Lprot, @@ -299,18 +283,14 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames, LC3_FLOAT *thresh_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ); void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ); void plc_phEcu_hq_ecu( LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, @@ -325,10 +305,8 @@ void plc_phEcu_hq_ecu( LC3_FLOAT *st_beta_mute, LC3_FLOAT *st_mag_chg_1st, LC3_FLOAT *st_Xavg, LC3_INT32 LA_ZEROS, LC3_FLOAT *x_tda, LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, LC3_FLOAT *corr_phase_dbg ,Fft* PhEcu_Fft,Fft* PhEcu_Ifft -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type, LC3_INT16 *nonpure_tone_flag_ptr -#endif ); void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands); @@ -339,12 +317,11 @@ void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, void processTdcApply_fl(const LC3_INT32 pitch_LC3_INT, const LC3_FLOAT *preemphFac, const LC3_FLOAT* A, const LC3_INT32 lpc_order, const LC3_FLOAT* pcmbufHist, const LC3_INT32 max_len_pcm_plc, const LC3_INT32 N, const LC3_INT32 frame_dms, const LC3_INT32 SampRate, const LC3_INT32 nbLostCmpt, const LC3_INT32 overlap, const LC3_FLOAT *stabFac, LC3_FLOAT harmonicBuf[MAX_PITCH], LC3_FLOAT synthHist[M], LC3_INT32* fract, LC3_INT16* seed, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth -#ifdef CR9_I_INC_TDC_FADEOUT_LEN ,LC3_UINT8 plc_fadeout_type -#endif + ,LC3_FLOAT* alpha_type_2_table ); void* balloc(void* base, size_t* base_size, size_t size); - +LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms); #endif diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c index b1b5d4b43b9ac9b54d48834fbb5c4cece45f9727..b8fc4e7985b2199ce23b6c68c2c503b5ced4ceb0 100644 --- a/lib_lc3plus/imdct.c +++ b/lib_lc3plus/imdct.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" /* Function expects already flipped window */ diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c index f09c53a5386fbf839d505a10bc0015d714734101..56a39286f84a23ee09d244e0bc5fd057ba248b08 100644 --- a/lib_lc3plus/lc3.c +++ b/lib_lc3plus/lc3.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "lc3.h" #include "defines.h" #include "functions.h" @@ -71,9 +71,7 @@ static int lc3plus_frame_size_supported(float frame_ms) { case 25: /* fallthru */ case 50: /* fallthru */ -#ifdef CR8_G_ADD_75MS case 75: /* fallthru */ -#endif case 100: return 1; default: break; } @@ -111,9 +109,12 @@ LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channel RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); - for (ch = 0; ch < channels; ch++) + if (lfe_channel_array != NULL) { - RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); + for (ch = 0; ch < channels; ch++) + { + RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); + } } return FillEncSetup(encoder, samplerate, channels, hrmode, lfe_channel_array); /* real bitrate check happens here */ @@ -304,7 +305,13 @@ int lc3plus_dec_get_delay(const LC3PLUS_Dec* decoder) LC3PLUS_Error lc3plus_dec_fl(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, void** output_samples, int bps, int bfi_ext) { - RETURN_IF(!decoder || !input_bytes || !output_samples, LC3PLUS_NULL_ERROR); + if (bfi_ext == 1) + { + RETURN_IF(!decoder || !output_samples, LC3PLUS_NULL_ERROR); + } else { + RETURN_IF(!decoder || !input_bytes || !output_samples, LC3PLUS_NULL_ERROR); + } + RETURN_IF(null_in_list((void**)output_samples, decoder->channels), LC3PLUS_NULL_ERROR); return Dec_LC3PLUS_fl(decoder, input_bytes, num_bytes, output_samples, bps, bfi_ext); } diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h index 0981cea84b9ee01072eb44c7c4ab01e7d11af2be..b5f8809e7e167302c30da51e2989743d09fd21fe 100644 --- a/lib_lc3plus/lc3.h +++ b/lib_lc3plus/lc3.h @@ -1,12 +1,11 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /*! \file lc3.h * This header provides the API for LC3plus. @@ -26,6 +25,7 @@ #ifndef _MSC_VER #include "options.h" +#include "wmc_auto.h" #include #else typedef unsigned char uint8_t; @@ -37,7 +37,7 @@ typedef __int32 int32_t; #define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro)) /*! Version number to ensure header and binary are matching. */ -#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 2) +#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 4) /*! Maximum number of supported channels. The actual binary might support * less, use lc3plus_channels_supported() to check. */ @@ -170,6 +170,7 @@ int lc3plus_samplerate_supported(int samplerate); * \param[in] samplerate Input sampling rate. Allowed sampling rates are: * 8000, 16000, 24000, 32000, 44100, 48000 * \param[in] hrmode High resolution mode. + * \param[in] lfe_channel_array Array containing activation of LFE mode for each individual channel. Can be NULL if LFE activation is not required. * \return LC3PLUS_OK on success or appropriate error code. */ LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc* encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]); @@ -386,7 +387,8 @@ LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channel * should provide enough space to hold at most LC3PLUS_MAX_SAMPLES. The * left channel is stored in output_samples[0], the right channel in * output_samples[1]. - * \param scratch Scratch parameter only works as dummy parameter to align fixed-point and floating-point APIs + * \param scratch Scratch parameter only works as dummy parameter to align fixed-point and floating-point APIs. + * \param[in] bfi_ext Bad Frame Indicator. 0: Good Frame. 1: Bad Frame, apply PLC. * \return Returns LC3PLUS_OK on success or appropriate error code. Note there is * a special case for LC3PLUS_DECODE_ERROR where the output is still valid. */ diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c index f1fc8fe714590f7565ef85e735ca5070dadcb9e7..75f8787e25ffdfc7b76bd29060db07c467ae17d9 100644 --- a/lib_lc3plus/lc3plus_fft.c +++ b/lib_lc3plus/lc3plus_fft.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" #include "fft/iis_fft.c" #include "fft/iisfft.c" diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h index 266f91a1656a6ff187e3c2f0cf1b3c39c9274ffc..0ea743b404b1111761c7522591c007311b731b71 100644 --- a/lib_lc3plus/license.h +++ b/lib_lc3plus/license.h @@ -1,19 +1,19 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" static const char *const LICENSE = "*******************************************************************************\n" - "* ETSI TS 103 634 V1.4.3 *\n" + "* ETSI TS 103 634 V1.5.1 *\n" "* Low Complexity Communication Codec Plus (LC3plus) *\n" "* Floating Point Software V%i.%i.%iETSI, " __DATE__ " *\n" "* Copyright licence is solely granted through ETSI Intellectual Property *\n" diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c index 286d8fa166bd26e29c3a09c1f3b2d610ad599526..3457b6ba66bd36e54cc7c98796919e82e898dfb5 100644 --- a/lib_lc3plus/ltpf_coder.c +++ b/lib_lc3plus/ltpf_coder.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); @@ -35,9 +35,7 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits -#ifdef CR9_K_REDUCE_NORM_CORR_TH , LC3_INT16 hrmode -#endif ) { LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)], sum = 0, cor_up[(MAX_PITCH_12K8 - MIN_PITCH_12K8) / 2] = {0}, *x; @@ -48,14 +46,12 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC LC3_FLOAT cor_tmp, cor_int_tmp, norm_corr = 0, cor[MAX_LEN_NR], cor_int[MAX_LEN_NR], sum1 = 0, sum2 = 0, sum3 = 0; LC3_FLOAT pitch = 0; -#ifdef CR9_K_REDUCE_NORM_CORR_TH LC3_FLOAT normCorrTh = 0.0f; if (hrmode) { normCorrTh = 0.4; } else { normCorrTh = 0.6; } -#endif /* Signal Buffer */ N = xLen - 1; @@ -72,11 +68,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC pitch_search_upsamp = 4; pitch_search_L_interpol1 = 4; -#ifdef CR9_K_REDUCE_NORM_CORR_TH if (pitch_ol_norm_corr > normCorrTh) { -#else - if (pitch_ol_norm_corr > 0.6) { -#endif /* Search Bounds */ t0_min = pitch_ol - pitch_search_delta; t0_max = pitch_ol + pitch_search_delta; diff --git a/lib_lc3plus/ltpf_decoder.c b/lib_lc3plus/ltpf_decoder.c index e95a274a46907cbb213f16c8f81006f86e1113ef..3ccd452bcb2f367c69ea1e9de832243cc309a81e 100644 --- a/lib_lc3plus/ltpf_decoder.c +++ b/lib_lc3plus/ltpf_decoder.c @@ -1,24 +1,22 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, LC3_INT* mem_pitch_int, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping - , LC3_INT *mem_ltpf_active -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , LC3_INT *mem_ltpf_active , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms -#endif ) { LC3_INT i, j, n, N, L_past_x, N4, N34, @@ -27,20 +25,14 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f LC3_FLOAT conf_alpha, gain, a1[12], a2[12], b1[11], b2[11], buf_x[4 * MAX_LEN], buf_y[4 * MAX_LEN], buf_z[4 * MAX_LEN], pitch, sum1, sum2; -#ifdef CR9_LTPF_REWRITE LC3_FLOAT *p_x, *p_y, *p_y2, *p_x_init, *p_y_init, *p_a1, *p_b1, *p_a2, *p_b2, fade_fac, current_fade_fac_up, current_fade_fac_down; -#endif -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH LC3_FLOAT pitch_fl_c_old, pitch_delta; -#endif const LC3_FLOAT *inter_filter[4], *tilt_filter[4]; #ifdef WMOPS push_wmops("process_ltpf_decoder_fl"); #endif -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH pitch_fl_c_old = (LC3_FLOAT) *mem_pitch_int + (LC3_FLOAT)*mem_pitch_fr / 4.0; -#endif conf_alpha = 0.85; if (bfi != 1) { @@ -226,12 +218,10 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f } /* First quarter of the current frame: cross-fading */ -#ifdef CR9_LTPF_REWRITE fade_fac = 1. / (LC3_FLOAT) N4; current_fade_fac_up = 0.f; current_fade_fac_down = 1.f; (void) p_x; (void) p_y; (void) p_a1; (void) p_b1; -#endif if (mem_param[1] == 0 && param[1] == 0) { memmove(&buf_y[L_past_y], &buf_x[L_past_x], sizeof(LC3_FLOAT) * N4); @@ -252,14 +242,9 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f j++; } -#ifdef CR9_LTPF_REWRITE buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_down * sum1 + current_fade_fac_down * sum2; current_fade_fac_down -= fade_fac; -#else - buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; -#endif } } else if (mem_param[1] == 0 && param[1] == 1) { @@ -278,12 +263,8 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f j++; } -#ifdef CR9_LTPF_REWRITE buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_up * sum1 + current_fade_fac_up * sum2; current_fade_fac_up += fade_fac; -#else - buf_y[L_past_y + n] = buf_x[L_past_x + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; -#endif } } else if (*mem_pitch_int == pitch_int && *mem_pitch_fr == pitch_fr) { for (n = 0; n < N4; n++) { @@ -304,7 +285,6 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f buf_y[L_past_y + n] = buf_x[L_past_x + n] - sum1 + sum2; } } else { -#ifdef CR9_LTPF_REWRITE p_x_init = &buf_x[L_past_x]; p_y_init = &buf_y[L_past_y - p1 + inter_len - 1]; p_y2 = &buf_y[L_past_y]; @@ -366,49 +346,8 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f p_y_init++; p_y2++; } -#else - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { - sum1 += b1[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p1 + inter_len - 1; i >= L_past_y + n - p1 - inter_len; i--) { - sum2 += a1[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; - } - - memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * (old_y_len + xLen)); - - for (n = 0; n < N4; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_y + n; i >= L_past_y + n - tilt_len; i--) { - sum1 += b2[j] * buf_z[i]; - j++; - } - - j = 0; - for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { - sum2 += a2[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + n] = buf_z[L_past_y + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; - } -#endif } -#ifdef CR9_LTPF_REWRITE /* Second quarter of the current frame */ if (param[1] == 0) { move_float(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], @@ -443,31 +382,6 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f p_y2++; } } -#else - /* Second quarter of the current frame */ - if (param[1] == 0) { - memmove(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], - sizeof(LC3_FLOAT) * ((L_past_x + N4 + N34) - (L_past_x + N4))); - } else { - for (n = 0; n < N34; n++) { - sum1 = 0; - sum2 = 0; - j = 0; - for (i = L_past_x + N4 + n; i >= L_past_x + n + N4 - tilt_len; i--) { - sum1 += b2[j] * buf_x[i]; - j++; - } - - j = 0; - for (i = L_past_y + N4 + n - p2 + inter_len - 1; i >= L_past_y + N4 + n - p2 - inter_len; i--) { - sum2 += a2[j] * buf_y[i]; - j++; - } - - buf_y[L_past_y + N4 + n] = buf_x[L_past_x + N4 + n] - sum1 + sum2; - } - } -#endif /* Output */ move_float(y, &buf_y[L_past_y], N); @@ -483,13 +397,11 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f *mem_pitch_int = pitch_int; *mem_pitch_fr = pitch_fr; *mem_gain = gain; - *mem_beta_idx = conf_beta_idx; -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + *mem_beta_idx = conf_beta_idx; if (bfi == 0 && hrmode == 1 && (frame_dms == 50 || frame_dms == 25)){ pitch_delta = LC3_FABS(pitch_fl_c_old - (LC3_FLOAT)pitch_int - (LC3_FLOAT)(pitch_fr / 4.0)); *rel_pitch_change = pitch_delta / MAX(pitch_fl_c_old, 1); } -#endif #ifdef WMOPS pop_wmops(); diff --git a/lib_lc3plus/mdct.c b/lib_lc3plus/mdct.c index ff4075977d1703dd8bfe1a6b834510b358eee3c0..4698afd4bfb043409a1736db099373ea210d7eb5 100644 --- a/lib_lc3plus/mdct.c +++ b/lib_lc3plus/mdct.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) @@ -31,7 +31,6 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h return NULL; } } -#ifdef CR8_G_ADD_75MS else if (frame_dms == 75) { switch (length) { case 60: @@ -50,7 +49,6 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h return NULL; } } -#endif else if (frame_dms == 50) { switch (length) { case 40: @@ -95,11 +93,9 @@ void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC if (frame_dms == 100) { mdct->leading_zeros = MDCT_la_zeroes[fs_idx]; } -#ifdef CR8_G_ADD_75MS else if (frame_dms == 75) { mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx]; } -#endif else if (frame_dms == 50) { mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx]; } diff --git a/lib_lc3plus/mdct_shaping.c b/lib_lc3plus/mdct_shaping.c index d3ca7dd953b35d25cbbb96b8526b89d5d2402671..296a8cd454980560dd31f199cffabbf729f8602f 100644 --- a/lib_lc3plus/mdct_shaping.c +++ b/lib_lc3plus/mdct_shaping.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c index e18eb52112d376c2b8be7034164b25edacc10df2..5d81392b214e9c599defa76f20afdfbebf1db3bb 100644 --- a/lib_lc3plus/near_nyquist_detector.c +++ b/lib_lc3plus/near_nyquist_detector.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,21 +8,14 @@ ******************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener -#ifdef CR8_E_TONE_DETECTOR - , const LC3_INT16 frame_dms, const LC3_INT16 hrmode) -#else -) -#endif + const LC3_INT bands_number, const LC3_FLOAT* ener , const LC3_INT16 frame_dms, const LC3_INT16 hrmode) { *near_nyquist_flag = 0; -#ifdef CR8_E_TONE_DETECTOR if (hrmode == 0){ -#endif if (fs_idx < 4) { LC3_INT i = 0; @@ -42,7 +35,6 @@ void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT f *near_nyquist_flag = 1; } } -#ifdef CR8_E_TONE_DETECTOR } else // hrmode == 1 { @@ -88,5 +80,4 @@ void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT f *near_nyquist_flag = 1; } } -#endif // CR8_E_TONE_DETECTOR } diff --git a/lib_lc3plus/noise_factor.c b/lib_lc3plus/noise_factor.c index 9cf130348f74dafed4f62698fa48a62ab1e71a2c..72b2602251430320fa436f899263786b1564a7e5 100644 --- a/lib_lc3plus/noise_factor.c +++ b/lib_lc3plus/noise_factor.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, @@ -29,12 +29,10 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3 nTransWidth = 1; startOffset = 12; break; -#ifdef CR8_G_ADD_75MS case 75: nTransWidth = 2; startOffset = 18; break; -#endif case 100: nTransWidth = 3; startOffset = 24; diff --git a/lib_lc3plus/noise_filling.c b/lib_lc3plus/noise_filling.c index 1ae4c8ab8c842ec16fb42b1697c17d3215219e14..f929338d0cabb0903ef6d4339496410e6bab3bbd 100644 --- a/lib_lc3plus/noise_filling.c +++ b/lib_lc3plus/noise_filling.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) @@ -27,12 +27,10 @@ void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, nTransWidth = 1; startOffset = 12; break; -#ifdef CR8_G_ADD_75MS case 75: nTransWidth = 2; startOffset = 18; break; -#endif case 100: nTransWidth = 3; startOffset = 24; diff --git a/lib_lc3plus/olpa.c b/lib_lc3plus/olpa.c index b1b8f2171c41f6c621ff4f671c6a870d2ba2729c..976f0a177e059c26a1b14ff3261c13742751506c 100644 --- a/lib_lc3plus/olpa.c +++ b/lib_lc3plus/olpa.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input); @@ -46,9 +46,7 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) } void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, -#ifdef CR9_F_PITCH_WIN_LEN_FIX LC3_INT* pitch_flag, -#endif LC3_INT* T0_out, LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms) { LC3_FLOAT norm_corr = 0, sum = 0, sum0 = 0, sum1 = 0, sum2 = 0, norm_corr2 = 0, *s6k4; @@ -56,7 +54,6 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 LC3_INT i = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0, delta = 0; len2 = len / 2; -#ifdef CR9_F_PITCH_WIN_LEN_FIX switch(frame_dms) { case 50: @@ -70,22 +67,11 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 break; default: -#endif delta = 0; acflen = len2; -#ifdef CR9_F_PITCH_WIN_LEN_FIX } -#endif mem_in_len = MAX_PITCH_6K4 + delta; - -#ifndef CR9_F_PITCH_WIN_LEN_FIX - if (frame_dms == 25) - { - mem_in_len += 16; - acflen += 16; - } -#endif /* Downsampling */ move_float(buf, mem_s12k8, 3); @@ -94,21 +80,10 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 filter_olpa(buf, R0, olpa_down2, len + 3); /* Compute autocorrelation */ -#ifdef CR9_F_PITCH_WIN_LEN_FIX s6k4 = &buf[mem_in_len - delta]; move_float(&buf[mem_in_len], R0, len2); move_float(buf, mem_s6k4, mem_in_len); move_float(mem_s6k4, &buf[len2], mem_in_len); -#else - s6k4 = &buf[mem_in_len]; - move_float(buf, mem_s6k4, mem_in_len); - move_float(s6k4, R0, len2); - move_float(mem_s6k4, &buf[len2], mem_in_len); - if (frame_dms == 25) - { - s6k4 = s6k4 - 16; - } -#endif for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) { sum = mac_loop(s6k4, &s6k4[-i], acflen); R0[i - MIN_PITCH_6K4] = sum; @@ -160,7 +135,6 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 } } -#ifdef CR9_F_PITCH_WIN_LEN_FIX switch(frame_dms) { case 50: @@ -188,11 +162,8 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 break; default: -#endif *mem_old_T0 = T0; -#ifdef CR9_F_PITCH_WIN_LEN_FIX } -#endif *T0_out = T0 * 2.0; *normcorr_out = norm_corr; diff --git a/lib_lc3plus/pc_apply.c b/lib_lc3plus/pc_apply.c index 4ca871f2fcca7b5c38ce7b24e9ebe73c41950fa3..a7113f1bc781f7e35e3d5852a95482591bac0ab3 100644 --- a/lib_lc3plus/pc_apply.c +++ b/lib_lc3plus/pc_apply.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processPcApply_fl(LC3_FLOAT *q_res, LC3_FLOAT *q_old_res, LC3_FLOAT *q_d_prev, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_FLOAT *prev_gg, LC3_FLOAT *fac, LC3_INT32 *pc_nbLostCmpt) { LC3_FLOAT gg, mean_nrg_low, mean_nrg_high, ener_prev, ener_curr, fac_local; diff --git a/lib_lc3plus/pc_classify.c b/lib_lc3plus/pc_classify.c index 9fa5f38d9cb232cee8f6b900c83e50d49f3ba99e..adb8a59713ef84fcd84f8abf7a6481a08030be38 100644 --- a/lib_lc3plus/pc_classify.c +++ b/lib_lc3plus/pc_classify.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen); void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi) diff --git a/lib_lc3plus/pc_main.c b/lib_lc3plus/pc_main.c index ead43deefe080feecf14ea8bb97cbd811945fa11..5ef1676d4838b5a814c5f51e1ceb5373184a5837 100644 --- a/lib_lc3plus/pc_main.c +++ b/lib_lc3plus/pc_main.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processPcMain_fl(LC3_INT32 *bfi, LC3PLUS_Dec* decoder, LC3_FLOAT *sqQdec, DecSetup* h_DecSetup, LC3_INT32 pitch_present, LC3_FLOAT stab_fac, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 fac_ns_idx, pcState *statePC, LC3_INT32 spec_inv_idx, LC3_INT32 yLen) { LC3_FLOAT fac; diff --git a/lib_lc3plus/pc_update.c b/lib_lc3plus/pc_update.c index 214ced77d07db3eaee4e9fe37d40822bc71a0b03..b24b2ea62a6848a876b85917fc41e6a090e82a2b 100644 --- a/lib_lc3plus/pc_update.c +++ b/lib_lc3plus/pc_update.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processPcUpdate_fl(LC3_INT32 bfi, LC3_FLOAT *q_res, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 rframe, LC3_INT32 *BW_cutoff_idx_nf, LC3_INT32 *prev_BW_cutoff_idx_nf, LC3_INT32 fac_ns_idx, LC3_FLOAT *prev_fac_ns, LC3_FLOAT *fac, LC3_FLOAT *q_old_res, LC3_FLOAT *prev_gg, LC3_INT32 spec_inv_idx, LC3_INT32 yLen) { diff --git a/lib_lc3plus/per_band_energy.c b/lib_lc3plus/per_band_energy.c index ec34c3d7dad0ac45baf99d87e4e23ebacd51c181..413b6cfd844e28d319d9fbd59032f95ff9dd5df4 100644 --- a/lib_lc3plus/per_band_energy.c +++ b/lib_lc3plus/per_band_energy.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) @@ -16,35 +16,29 @@ void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_ LC3_INT i, j, start, stop, maxBwBin; LC3_FLOAT sum; -# ifdef ENABLE_HR_MODE_FL +#ifdef ENABLE_HR_MODE_FL if (hrmode) { maxBwBin = MAX_BW_HR; } else -# else +#else UNUSED(hrmode); -# endif +#endif { maxBwBin = MAX_BW; } switch (frame_dms) { -# ifdef ENABLE_2_5MS_MODE case 25: maxBwBin = maxBwBin >> 2; break; -# endif -# ifdef ENABLE_5MS_MODE case 50: maxBwBin = maxBwBin >> 1; break; -# endif -#ifdef CR8_G_ADD_75MS case 75: maxBwBin = (maxBwBin >> 2) * 3; break; -#endif } for (i = 0; i < bands_number; i++) { diff --git a/lib_lc3plus/plc_classify.c b/lib_lc3plus/plc_classify.c index e45f08747d85c29eedc3fc9020ceb7852913187a..f1f1878d4bf644657eaaa09bbdcce8f976b633d6 100644 --- a/lib_lc3plus/plc_classify.c +++ b/lib_lc3plus/plc_classify.c @@ -1,18 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" -#ifdef CR8_A_PLC_FADEOUT_TUNING - static LC3_INT32 change_bit_at_position(LC3_INT32 value, LC3_UINT8 bit_position, LC3_INT8 bit) { LC3_INT32 helper_mask = ~(1 << bit_position); @@ -23,7 +21,7 @@ static LC3_INT32 change_bit_at_position(LC3_INT32 value, LC3_UINT8 bit_position, static void update_bit_and_byte_positions(LC3_INT16 longterm_analysis_counter_max_bytebuffer, LC3_INT8 *byte_position, LC3_INT8 *bit_position) { - if (*bit_position == 30) + if (*bit_position == 29) { *bit_position = 0; @@ -54,11 +52,7 @@ static void array_insert_and_shift(LC3_INT32 *array, LC3_UINT8 value, LC3_INT16 array[*byte_position] = current_byte; } -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 longterm_analysis_counter_max) -#else -static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 *counter_phecu, LC3_INT16 overall_counter, LC3_INT16 longterm_analysis_counter_max) -#endif { int i, k; LC3_INT32 current_byte_tdc = 0, current_byte_ns = 0; @@ -87,11 +81,7 @@ static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int lengt *counter_tdc = counter_loc_tdc; *counter_ns = counter_loc_ns; -#ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - *counter_phecu = overall_counter - counter_loc_tdc - counter_loc_ns; -#endif } -#endif static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr); static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *bands_offset, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc); @@ -103,45 +93,27 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n ) { LC3_FLOAT sc, class; -#ifdef CR8_A_PLC_FADEOUT_TUNING int fs_idx_tmp; -#endif if (plcAd) { *xcorr = 0; } -#ifdef CR8_A_PLC_FADEOUT_TUNING fs_idx_tmp = FS2FS_IDX(fs); /* Save statistics for 24 kHz, 48 kHz and 96 kHz */ if ((bfi == 1) || ((bfi >= 0) && (bfi <= 2) && ((fs_idx_tmp == 2) || (fs_idx_tmp == 4) || (fs_idx_tmp == 5)))) /* Partial Concealment PC(bfi==2) requires allowing value 2 to pass thru as well */ -#else - if (bfi == 1) -#endif { -#ifdef CR8_A_PLC_FADEOUT_TUNING if (bfi == 1) { *nbLostCmpt = *nbLostCmpt + 1; } -#else - *nbLostCmpt = *nbLostCmpt + 1; -#endif /* Use pitch correlation at ltpf integer lag if available */ -#ifdef CR8_A_PLC_FADEOUT_TUNING if ((*nbLostCmpt == 1) || (bfi != 1) )/* PC(bfi==2) requires allowing 2 to pass thru as well */ -#else - if (*nbLostCmpt == 1) -#endif { -#ifdef CR8_A_PLC_FADEOUT_TUNING *concealMethod = 4; /* Noise Substitution */ UNUSED(plcMeth); -#else - *concealMethod = plcMeth; // this is a dangerous mapping! -#endif /* Advanced PLC */ if (pitch_int > 0) @@ -157,46 +129,29 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n if (frame_dms == 100 && hrmode == 0) { *concealMethod = 2; /* PhaseEcu selected */ -#ifdef CR8_A_PLC_FADEOUT_TUNING array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif } else { -#ifndef CR9_G_PLC_NS_TDC_FIX - *concealMethod = 4; /* Noise Substitution */ -#endif -#ifdef CR8_A_PLC_FADEOUT_TUNING array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif } } -#ifdef CR8_A_PLC_FADEOUT_TUNING else { array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); } -#endif } else { *concealMethod = 4; /* Noise Substitution */ -#ifdef CR8_A_PLC_FADEOUT_TUNING array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif } -#ifdef CR8_A_PLC_FADEOUT_TUNING -# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max); -# else - array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, &plcAd->longterm_counter_plcPhaseEcu, plcAd->overall_counter, plcAd->longterm_analysis_counter_max); -# endif update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); -#endif } } } diff --git a/lib_lc3plus/plc_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c index a81af2218b920bddbda5b181b32ba4a55fced329..121c2f06a22d58316ff9259997dd435c3b8b7b2d 100644 --- a/lib_lc3plus/plc_compute_stab_fac.c +++ b/lib_lc3plus/plc_compute_stab_fac.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - static void processPlcComputeStabFac_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_INT32 prev_bfi, LC3_FLOAT *stab_fac); void processPlcComputeStabFacMain_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_FLOAT *old_old_scf_q, LC3_INT32 bfi, LC3_INT32 prev_bfi, diff --git a/lib_lc3plus/plc_damping_scrambling.c b/lib_lc3plus/plc_damping_scrambling.c index a863c1621a01fd8bf5ace1b40d58044fb32ec66b..ac4526b4ec698c7a90fca4e71c832dbf54245117 100644 --- a/lib_lc3plus/plc_damping_scrambling.c +++ b/lib_lc3plus/plc_damping_scrambling.c @@ -1,26 +1,23 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc, LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, LC3_FLOAT *cum_fflcAtten -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ) { @@ -36,31 +33,25 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, processDampScramb = 1; } -#ifdef CR8_A_PLC_FADEOUT_TUNING if (ns_nbLostCmpt == 1) { *cum_fading_slow = 1; *cum_fading_fast = 1; *cum_fflcAtten = 1; - } -#endif + } if ( bfi == 1 ) { processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt, stabFac, processDampScramb, cum_fflcAtten, pitch_present_bfi1, frame_dms, cum_fading_slow, cum_fading_fast, ns_seed, 0 -#ifdef CR8_A_PLC_FADEOUT_TUNING , plc_fadeout_type -#endif ); } else /* bfi == 2 */ { processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt_pc, stabFac, processDampScramb, cum_fflcAtten, pitch_present_bfi2, frame_dms, cum_fading_slow, cum_fading_fast, pc_seed, spec_inv_idx -#ifdef CR8_A_PLC_FADEOUT_TUNING , plc_fadeout_type -#endif ); processPlcUpdateSpec_fl(spec_prev, spec, yLen); } @@ -70,9 +61,7 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ) { LC3_INT32 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, x, b, i, ad_ThreshFac_start; @@ -80,16 +69,6 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n frame_energy = 0; -#ifndef CR8_A_PLC_FADEOUT_TUNING - /* Main process */ - if (nbLostCmpt == 1) - { - *cum_fading_slow = 1; - *cum_fading_fast = 1; - *cum_fflcAtten = 1; - } -#endif - slow = 0.8 + 0.2 * (*stabFac); fast = 0.3 + 0.2 * (*stabFac); @@ -103,27 +82,20 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n slow = LC3_SQRT(slow); fast = LC3_SQRT(fast); break; -#ifdef CR8_G_ADD_75MS case 75: slow = LC3_SQRT(LC3_SQRT(slow*slow*slow)); fast = LC3_SQRT(LC3_SQRT(fast*fast*fast)); break; -#endif } -#ifdef CR8_A_PLC_FADEOUT_TUNING if (plc_fadeout_type == 0) { -#endif *cum_fading_slow = *cum_fading_slow * slow; *cum_fading_fast = *cum_fading_fast * fast; -#ifdef CR8_A_PLC_FADEOUT_TUNING } -#endif if (processDampScramb == 1) { -#ifdef CR8_A_PLC_FADEOUT_TUNING if (plc_fadeout_type != 0) { if (nbLostCmpt < (4 * (100.0 / (LC3_FLOAT)frame_dms))) { @@ -140,7 +112,6 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n cum_fading_slow_local = *cum_fading_slow; } else { -#endif fflcAtten = 1; cum_fading_slow_local = *cum_fading_slow; cum_fading_fast_local = *cum_fading_fast; @@ -158,9 +129,7 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n { case 25: fflcAtten = PLC34_ATTEN_FAC_025; break; case 50: fflcAtten = PLC34_ATTEN_FAC_050; break; -#ifdef CR8_G_ADD_75MS case 75: fflcAtten = PLC34_ATTEN_FAC_075; break; -#endif case 100: fflcAtten = PLC34_ATTEN_FAC_100; break; } } @@ -198,37 +167,25 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n } randThreshold = -32768 * linFuncStartStop; -#ifdef CR8_A_PLC_FADEOUT_TUNING } -#endif for (i = spec_inv_idx; i < yLen; i++) { *seed = 16831 + *seed * 12821; *seed = (LC3_INT16)(*seed); - if (*seed == 32768) - { - *seed -= 32768; - } if (*seed < 0) { -#ifdef CR8_A_PLC_FADEOUT_TUNING if (plc_fadeout_type != 0 || pitch_present == 0 || *seed < randThreshold ) -#else - if (pitch_present == 0 || *seed < randThreshold) -#endif { spec[i] = -spec[i]; } } } -#ifdef CR8_A_PLC_FADEOUT_TUNING if (plc_fadeout_type == 0) { -#endif ad_ThreshFac_start = 10; ad_ThreshFac_end = 1.2; ad_threshFac = (ad_ThreshFac_start - ad_ThreshFac_end) * linFuncStartStop + ad_ThreshFac_end; @@ -249,17 +206,11 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n energThreshold = LC3_SQRT(ad_threshFac * mean_energy); fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; -#ifdef CR8_A_PLC_FADEOUT_TUNING } -#endif for (i = spec_inv_idx; i < yLen; i++) { -#ifdef CR8_A_PLC_FADEOUT_TUNING if (plc_fadeout_type != 0 || LC3_FABS(spec[i]) < energThreshold ) -#else - if (LC3_FABS(spec[i]) < energThreshold) -#endif { m = cum_fading_slow_local; n = 0; diff --git a/lib_lc3plus/plc_main.c b/lib_lc3plus/plc_main.c index 4fc19f6053d6fe8ffd8c3102462d7dd3ab938a11..01fe7b237c11233b5d490cb83ad291b016da4560 100644 --- a/lib_lc3plus/plc_main.c +++ b/lib_lc3plus/plc_main.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, @@ -25,15 +25,11 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* LC3_FLOAT phEcu_env_stab_local[1]; LC3_FLOAT phEcu_pfind_sens[1]; -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT16 consecutiveLostThreshold = 0; -#endif -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER LC3_INT16 thresh_tdc_cnt; LC3_INT16 thresh_ns_cnt; LC3_INT16 thresh_tdc_ns_cnt; -#endif prev_bfi_plc2 = 1; if (PlcSetup->nbLostCmpt == 0) @@ -49,12 +45,6 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* } pitch_classifier = ltpf_pitch_int; -#ifdef NONBE_PLC_CLASSIFER_LAG_FIX - if (ltpf_pitch_fr > 2) - { - pitch_classifier++; - } -#endif processPlcClassify_fl(plcMeth, &h_DecSetup->concealMethod, &PlcSetup->nbLostCmpt, bfi, &xcorr, decoder->frame_length, decoder->frame_dms, pitch_classifier, decoder->fs, @@ -63,44 +53,34 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* if (bfi == 1) { -# ifdef CR8_A_PLC_FADEOUT_TUNING switch(decoder->frame_dms) { case 25: consecutiveLostThreshold = 16; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT; thresh_ns_cnt = THRESH_025_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT; -#endif + thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT; break; case 50: consecutiveLostThreshold = 8; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT; thresh_ns_cnt = THRESH_050_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT; -#endif + thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT; break; case 75: consecutiveLostThreshold = 6; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT; thresh_ns_cnt = THRESH_075_DMS_NS_CNT; - thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT; -#endif + thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT; break; case 100: consecutiveLostThreshold = 4; -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT; thresh_ns_cnt = THRESH_100_DMS_NS_CNT; thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT; -#endif break; default: assert(0); } if (decoder->fs_idx == 2 || decoder->fs_idx >= 4) { -#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER if (PlcAdvSetup->longterm_counter_plcTdc < thresh_tdc_cnt){ PlcAdvSetup->plc_fadeout_type = 1; } @@ -113,41 +93,14 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* else { PlcAdvSetup->plc_fadeout_type = 0; } -#else - if (((PlcAdvSetup->longterm_counter_plcPhaseEcu < PlcAdvSetup->longterm_counter_plcTdc*FAC1_FADEOUT) || - (PlcAdvSetup->longterm_counter_plcPhaseEcu < PlcAdvSetup->longterm_counter_plcNsAdv*FAC1_FADEOUT)) && - (PlcAdvSetup->longterm_counter_plcTdc / (PlcAdvSetup->longterm_counter_plcNsAdv + LC3_EPS) < FAC2_FADEOUT)) - { - PlcAdvSetup->plc_fadeout_type = 0; - } else { - if ((PlcAdvSetup->longterm_counter_plcPhaseEcu > FAC3_FADEOUT * PlcAdvSetup->longterm_counter_plcTdc) || - (PlcAdvSetup->longterm_counter_plcPhaseEcu > FAC3_FADEOUT * PlcAdvSetup->longterm_counter_plcNsAdv)) - { - PlcAdvSetup->plc_fadeout_type = 1; - } else { - PlcAdvSetup->plc_fadeout_type = 0; - } - } -#endif if ((PlcAdvSetup->overall_counter - (int)(PLC_LONGTERM_ANALYSIS_STARTUP_FILL * PlcAdvSetup->longterm_analysis_counter_max)) < 0) { PlcAdvSetup->plc_fadeout_type = 0; } -#ifndef CR9_H_REMOVE_SWITCH_TO_PLC_NS - if (PlcSetup->nbLostCmpt >= consecutiveLostThreshold && PlcAdvSetup->plc_fadeout_type == 1) - { - if ( h_DecSetup->concealMethod == 3 ) - { - h_DecSetup->concealMethod = 4; - } - } -#endif -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH if (h_DecSetup->rel_pitch_change > REL_PITCH_THRESH && hrmode == 1 && (decoder->frame_dms == 50 || decoder->frame_dms == 25) ){ PlcAdvSetup->plc_fadeout_type = 2; } else -#endif if ( h_DecSetup->concealMethod != 2 ) { /* not PhECU */ if (PlcSetup->nbLostCmpt < consecutiveLostThreshold ) @@ -158,11 +111,7 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* } else { PlcAdvSetup->plc_fadeout_type = 0; } -# endif -#ifdef PLC_CR8_A_PRINTF - printf("plc_fadeout_type = %d\n", PlcAdvSetup->plc_fadeout_type); -#endif switch (h_DecSetup->concealMethod) { case 2: @@ -175,7 +124,7 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* if (decoder->frame_dms != 100) { - // muting, if frame size changed during phaseECU concealment + /* muting, if frame size changed during phaseECU concealment */ memset(q_d_fl_c, 0, sizeof(LC3_FLOAT) * decoder->frame_length); h_DecSetup->alpha = 0; break; @@ -265,10 +214,8 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* , &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft) -#ifdef CR8_A_PLC_FADEOUT_TUNING ,PlcAdvSetup->plc_fadeout_type, &(PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag) /* nonpure tone flag */ -#endif ); @@ -294,9 +241,8 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder->frame_dms, decoder->fs, PlcSetup->nbLostCmpt, decoder->frame_length - decoder->la_zeroes, &PlcAdvSetup->stabFac, PlcAdvSetup->PlcTdcSetup.harmonicBuf, PlcAdvSetup->PlcTdcSetup.synthHist, &PlcAdvSetup->PlcTdcSetup.fract, &PlcAdvSetup->PlcTdcSetup.seed, &PlcAdvSetup->PlcTdcSetup.gain_c, &h_DecSetup->alpha, synth -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - ,PlcAdvSetup->plc_fadeout_type -#endif + , PlcAdvSetup->plc_fadeout_type + , decoder->alpha_type_2_table ); processTdcTdac_fl(synth, decoder->imdct_win, decoder->frame_length, decoder->la_zeroes, h_DecSetup->imdct_mem); diff --git a/lib_lc3plus/plc_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c index 92f8b3cf214f7cc84abc33fa51dacbec4330cd81..dc8e4d56fc6d5b7f2d9980ec7fd2c580d35aa3c8 100644 --- a/lib_lc3plus/plc_noise_substitution.c +++ b/lib_lc3plus/plc_noise_substitution.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processNoiseSubstitution_fl(LC3_FLOAT* spec, LC3_FLOAT* spec_prev, LC3_INT32 yLen) { memmove(spec, spec_prev, sizeof(LC3_FLOAT) * yLen); diff --git a/lib_lc3plus/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c index 2a580024f037c2bb842ba777a1e73b2a8b9e2e45..7abb19813ca56889a2b025de577738de0f24d9f2 100644 --- a/lib_lc3plus/plc_phecu_f0_refine_first.c +++ b/lib_lc3plus/plc_phecu_f0_refine_first.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - void plc_phEcu_F0_refine_first( LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ LC3_INT32 n_plocs, LC3_FLOAT *f0est, /* i/o f0est */ diff --git a/lib_lc3plus/plc_phecu_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c index 4aebbfa88545a47e611bcf6fb992af5e819eaaae..bb7be94bf06ceea303394020cc999654054372eb 100644 --- a/lib_lc3plus/plc_phecu_fec_hq.c +++ b/lib_lc3plus/plc_phecu_fec_hq.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - LC3_FLOAT plc_phEcu_imax2_jacobsen_mag(const Complex *y, LC3_FLOAT *c_jacobPtr) { LC3_FLOAT posi; diff --git a/lib_lc3plus/plc_phecu_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c index 112d965a4963e6775c418c137e4c37c6fb8dbf1b..8b2b981582dce5c62a3048e82145821ccabd6f7b 100644 --- a/lib_lc3plus/plc_phecu_hq_ecu.c +++ b/lib_lc3plus/plc_phecu_hq_ecu.c @@ -1,19 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - - void plc_phEcu_hq_ecu( LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, LC3_FLOAT *xfp, LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, LC3_INT32 fs, @@ -26,9 +24,7 @@ void plc_phEcu_hq_ecu( LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, LC3_FLOAT *corr_phase_dbg, Fft *PhEcu_Fft, Fft *PhEcu_Ifft -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type, LC3_INT16 *nonpure_tone_flag_ptr /* nonpure tone flag */ -#endif ) { @@ -77,19 +73,13 @@ void plc_phEcu_hq_ecu( xfp_local_rnd[i] = 0.0; } } -#ifdef CR8_A_PLC_FADEOUT_TUNING *nonpure_tone_flag_ptr = -1; /* set nonpure tone flag for new analysis */ -#endif - *time_offs = 0; burst_len = (*time_offs / L + 1); plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr , old_grp_shape, old_EwPtr, st_beta_mute, st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL - -#ifdef CR8_A_PLC_FADEOUT_TUNING - ,plc_fadeout_type -#endif + , plc_fadeout_type ); plc_phEcu_spec_ana(xfp_local_rnd, Lprot, winWhr, pfind_sensPtr, plocs, n_plocs, f0est, X_sav_m, &LXsav, f0binPtr, f0ltpGainPtr, fs_idx, PhEcu_Fft); @@ -102,9 +92,7 @@ void plc_phEcu_hq_ecu( plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr, old_grp_shape, old_EwPtr, st_beta_mute, st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL -#ifdef CR8_A_PLC_FADEOUT_TUNING - ,plc_fadeout_type -#endif + , plc_fadeout_type ); } @@ -120,10 +108,8 @@ void plc_phEcu_hq_ecu( /* inplace X_out_m update */ plc_phEcu_subst_spec(plocs, *n_plocs, f0est, *time_offs, X_out_m, LXsav, mag_chg, &seed, alpha, beta, st_Xavg, t_adv, Lprot, delta_corr, -#ifdef CR8_A_PLC_FADEOUT_TUNING plc_fadeout_type, nonpure_tone_flag_ptr, /* nonpure_tone_flag , a state updated here */ -#endif NULL, NULL, NULL); diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis.c b/lib_lc3plus/plc_phecu_lf_peak_analysis.c index 225aa52560ca009e822fc97eae5c650e400bbfbf..a53b6a4352ffd7d53cb0e48fbcddfe055333b78b 100644 --- a/lib_lc3plus/plc_phecu_lf_peak_analysis.c +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - void plc_phEcu_LF_peak_analysis(LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ LC3_INT32 *n_plocs, /* i/o 0.. MAX_PLOCS */ LC3_FLOAT *f0est, /* i/o Q16*/ diff --git a/lib_lc3plus/plc_phecu_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c index e56cb3dd759de8a5985f1cecc0c9675fd9d257d5..412c5205ca5a45a2d989a958021b16c8438fd605 100644 --- a/lib_lc3plus/plc_phecu_rec_frame.c +++ b/lib_lc3plus/plc_phecu_rec_frame.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - void plc_phEcu_rec_frame(Complex *X_in, LC3_INT32 L, LC3_INT32 Lecu, @@ -52,11 +51,7 @@ void plc_phEcu_rec_frame(Complex *X_in, UNUSED(xsubst_dbg); UNUSED(xsubst_LL); -#ifdef CR8_A_PLC_FADEOUT_TUNING - fs_idx = FRAME2FS_IDX_10MS(L); -#else - fs_idx = FRAME2FS_IDX(L); -#endif + fs_idx = FRAME2FS_IDX_10MS(L); hannOla = hannOla_wins[fs_idx]; X_in[0].i = X_in[Lprot / 2].r; /* move fs/2 real to imag part of X_in[0]*/ diff --git a/lib_lc3plus/plc_phecu_setf0hz.c b/lib_lc3plus/plc_phecu_setf0hz.c index 7bdb0a8c5cf4aedf41d4c55cc31b2b62fb2bb792..c67f96d41028d366871894be7936f5e87fe52602 100644 --- a/lib_lc3plus/plc_phecu_setf0hz.c +++ b/lib_lc3plus/plc_phecu_setf0hz.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT * old_pitchPtr) { LC3_FLOAT result; diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c index 313b33877718c764ef49353db37b38e8334ce8e2..c8b46309ba6a36d452aa4b1b2781f23f8145dcfb 100644 --- a/lib_lc3plus/plc_phecu_spec_ana.c +++ b/lib_lc3plus/plc_phecu_spec_ana.c @@ -1,21 +1,19 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - #define PEAK_LOCATOR_RES_FX 1 /* fixed point resolution minimum value */ - static LC3_INT16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ const LC3_INT16 *inp, /* i : vector */ const LC3_INT16 len, /* i : length */ diff --git a/lib_lc3plus/plc_phecu_subst_spec.c b/lib_lc3plus/plc_phecu_subst_spec.c index d494af826f5806ccfb4fe1bacf13074293a3cd28..62a1d4434e8737437bdcbfa55727ca9e59e07006 100644 --- a/lib_lc3plus/plc_phecu_subst_spec.c +++ b/lib_lc3plus/plc_phecu_subst_spec.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" #include "constants.h" @@ -17,20 +17,15 @@ static LC3_INT32 own_rand(LC3_INT32 seed); static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOAT cos_F); static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F); -#ifdef CR8_A_PLC_FADEOUT_TUNING - #define ONE_SIDED_SINE_WIDTH (4) /* expected pure sine main lobe maximum width (4+1+4) bins *62.5 hz/bin => approx 560 Hz total width */ static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_INT32 n_plocs, const Complex* X, const LC3_FLOAT* Xavg, const LC3_INT32 Lprot); -#endif void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT16 fadeout, /* need for DC muting */ LC3_INT16* nonpure_tone_flag_ptr, -#endif LC3_FLOAT *corr_phase_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg) { @@ -43,9 +38,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_FLOAT Xph; LC3_FLOAT seed_local; LC3_INT32 binCounter = 1, subInd = 0; -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT16 fs_idx; -#endif UNUSED(corr_phase_dbg); UNUSED(X_i_new_re_dbg); @@ -58,13 +51,12 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, t_adv = t_adv_in + time_offs; for (i = 0; i < n_plocs; i++) { - corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv; + corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI_LC3PLUS * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv; } // EVOLVE PHASE ----------------- - one_peak_flag_mask = -1; -#ifdef CR8_A_PLC_FADEOUT_TUNING + one_peak_flag_mask = -1; fs_idx = (LC3_INT16)LC3_FLOOR((LC3_FLOAT)Lprot / 160.0); /* aquire, fs_idx for 10 ms frame sizes */ if (n_plocs < 3 && n_plocs > 0) { @@ -83,11 +75,6 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, } } -#else - if (n_plocs < 3 && n_plocs > 0) { - one_peak_flag_mask = 0; - } -#endif noise_mag_scale = 0; if (n_plocs == 0 || time_offs != 0) { @@ -99,10 +86,6 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, X[X_len-1] = realtoc(0); } -#ifdef CR8_A_PLC_FADEOUT_TUNING -#if 0 - /* align DC fs/2 muting to BASOP */ -#endif /* binary selection of fadeout scheme */ assert(PLC2_FADEOUT_LONG_IN_MS >= PLC2_FADEOUT_IN_MS_MIN && PLC2_FADEOUT_IN_MS >= PLC2_FADEOUT_IN_MS_MIN); assert(PLC2_FADEOUT_LONG_IN_MS <= PLC2_FADEOUT_IN_MS_MAX && PLC2_FADEOUT_IN_MS <= PLC2_FADEOUT_IN_MS_MAX); @@ -124,7 +107,6 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, /* start fs/by2 attenuation */ X[X_len - 1].r = alpha[(xavg_N_grp[fs_idx] - 1)] * X[X_len - 1].r; } -#endif if (n_plocs != 0) { for (i = 0; i < n_plocs; i++) { @@ -145,7 +127,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, seed_local = (LC3_FLOAT)rand_phase((LC3_INT32)seed_local, &cos_F); X_i = X[binCounter]; - X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0)); + X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI_LC3PLUS*seed_local / (LC3_FLOAT)32768.0)); seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); @@ -164,7 +146,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, tmp = 0; X_i_new = realtoc(0); } - X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0))); + X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI_LC3PLUS*seed_local / (LC3_FLOAT)32768.0))); } else { if (one_peak_flag_mask == 0) { @@ -196,9 +178,9 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, X_i = X[binCounter]; { - LC3_INT32 nrep =(LC3_INT32) LC3_FLOOR(Xph / (2.0f*(LC3_FLOAT)M_PI)); + LC3_INT32 nrep =(LC3_INT32) LC3_FLOOR(Xph / (2.0f*(LC3_FLOAT)M_PI_LC3PLUS)); - X_i_new = cmul(X_i, cexpi(Xph - (2.0f*(LC3_FLOAT)M_PI*(LC3_FLOAT)nrep))); + X_i_new = cmul(X_i, cexpi(Xph - (2.0f*(LC3_FLOAT)M_PI_LC3PLUS*(LC3_FLOAT)nrep))); } @@ -212,7 +194,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, assert(alpha_local == mag_chg_local); tmp = beta_local * Xavg[subInd]; - X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0))); + X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI_LC3PLUS*seed_local / (LC3_FLOAT)32768.0))); } else { @@ -234,7 +216,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, seed_local = (LC3_FLOAT)rand_phase((LC3_INT32)seed_local, &cos_F); X_i = X[binCounter]; - X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI*seed_local/(LC3_FLOAT)32768.0)); + X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI_LC3PLUS*seed_local/(LC3_FLOAT)32768.0)); seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); @@ -258,7 +240,7 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, tmp = 0; } - X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local/(LC3_FLOAT)32768.0))); + X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI_LC3PLUS*seed_local/(LC3_FLOAT)32768.0))); } else { @@ -297,13 +279,10 @@ static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOA static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F) { LC3_FLOAT seed = (LC3_FLOAT)own_rand(seed_in); - *cos_F = LC3_COS((LC3_FLOAT)M_PI*seed/(LC3_FLOAT)32768.0); + *cos_F = LC3_COS((LC3_FLOAT)M_PI_LC3PLUS*seed/(LC3_FLOAT)32768.0); return (LC3_INT32) seed; } - -#ifdef CR8_A_PLC_FADEOUT_TUNING - static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_INT32 n_plocs, const Complex* X, const LC3_FLOAT* Xavg, const LC3_INT32 Lprot) { @@ -417,12 +396,6 @@ static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_I { /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */ -#if 0 - /* note: in BASOP the Xavg ratios below are calculated in log2 domain on a maximally upshifted Xavg vector. - if Xavg is an all zero vector in BASOP, then the nonpure_tone_detect flag is or'ed with 0x100 , - to trigger normal valley noise generation */ -#endif - /* verify that an assumed clean sine does not have any odd HF content indications by thresholding the accumulated delta rise in LF/HF side lobes */ for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++) { tmp = (Xavg[i + 1] + LC3_EPS) / (Xavg[i] + LC3_EPS); @@ -460,5 +433,3 @@ static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_I return nonpure_tone_detect; } -#endif /* CR8_A_PLC_FADEOUT_TUNING */ - diff --git a/lib_lc3plus/plc_phecu_tba_per_band_gain.c b/lib_lc3plus/plc_phecu_tba_per_band_gain.c index 507f45a647d1a6c15ca0533de989fda31fdd1fa1..8bf33b88535a618bcf0a46a73f22533ef9f67172 100644 --- a/lib_lc3plus/plc_phecu_tba_per_band_gain.c +++ b/lib_lc3plus/plc_phecu_tba_per_band_gain.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) { LC3_INT32 i; diff --git a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c index b4727cfd4cc77275fe9d60500b4676c32ebd5e26..ca58ade71e7e11e8f2ec7ba230455a157699a188 100644 --- a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c +++ b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c @@ -1,18 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - void plc_phEcu_tba_spect_Xavg(LC3_INT32 fs_idx, LC3_INT32 n_grp, LC3_FLOAT *oold_spec_shape, LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spec_shape, LC3_FLOAT *old_EwPtr, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *Xavg) diff --git a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c index 3b58d92b427b0b456ac795bad23a10df60c9621c..0ea04fe1af96c1fae63a43f9c1f7ec04b3593893 100644 --- a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c +++ b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c @@ -1,30 +1,23 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - #define BETA_MUTE_FAC 0.5 /* % attenuation factor per additional bad frame, FX uses 0.5 (shift right with 1 bit) */ #define BETA_MUTE_FAC_INI 0.5 - - #define OFF_FRAMES_LIMIT 30 /* 300 ms for LC3 10 ms */ - - - #define LGW32k 7 #define LGW16k 5 - /* Tables for attentuation of mag_chg, copied from FX */ /* Tables are in Q15 */ /* 0.3 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */ @@ -40,15 +33,8 @@ const LC3_INT32 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { 32767, 31293, 29885, 28 #ifdef PLC2_FADEOUT_IN_MS #if PLC2_FADEOUT_IN_MS == 0 -#ifndef CR8_A_PLC_FADEOUT_TUNING -/* default setting only requires two tables */ -const Word16* const POW_ATT_TABLES[1 + 2] = -{ NULL, POW_ATT_TABLE1/*1 0.3dB steps */ , POW_ATT_TABLE0/*2 0.4 dB steps*/, -}; -#endif #else -#ifdef CR8_A_PLC_FADEOUT_TUNING const LC3_INT32 POW_ATT_TABLE_p3x9_14_7[OFF_FRAMES_LIMIT + 1] = { 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, /* 9 times .3dB steps , 14 6 dB steps, 7 muted steps */ @@ -60,8 +46,6 @@ const LC3_INT32 POW_ATT_TABLE_p4x9_14_7[OFF_FRAMES_LIMIT + 1] = 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, /* 9 times .4dB steps , 14 6 dB steps, 7 muted steps */ 10825, 5413, 2706, 1353, 677, 338, 169, 85, 42, 21, 11, 5, 3, 1, 0, 0,0,0,0,0,0 }; -#endif - const LC3_INT32 POW_ATT_TABLE_p3x8_6[] = { 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, @@ -99,11 +83,6 @@ const LC3_INT32 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { 32, 16, 8, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#ifdef CR8_A_PLC_FADEOUT_TUNING -#if 0 -/* POW_ATT_TABLES now ordered logically based on initial slow muting phase time */ -/* POW_ATT_TABLES[ind] is used after the initial gain==1.0 no energy muting phase */ -#endif const LC3_INT32 *const POW_ATT_TABLES[1 + 12] = { NULL, /*0.3dB col , 0.4dB col */ @@ -115,17 +94,6 @@ const LC3_INT32 *const POW_ATT_TABLES[1 + 12] = /*11*/POW_ATT_TABLE1, POW_ATT_TABLE0, /* 15 0.3dB, 14 6dB , 1 mute */ /* 0.4dB version */ /* original curves */ }; -#else - -const LC3_INT32* const POW_ATT_TABLES[1 + 10] = -{ NULL, - POW_ATT_TABLE1 , POW_ATT_TABLE0, /* .3dB x16,16 6dB steps */ /* .4dB x16, 16 6dB steps */ /*original/default */ - POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* .3dB x8, 24 6dB steps */ /* .4dB x8, 24 6dB steps */ - POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* .3dB x4, 28 6dB steps */ /* .4dB x4, 28 6dB steps */ - POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */ - POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */ -}; -#endif #endif #endif @@ -133,9 +101,7 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames_dbg, LC3_FLOAT *thresh_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ) { @@ -148,19 +114,8 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL LC3_INT32 burst_att_thresh; LC3_INT32 att_per_frame_idx; LC3_INT32 att_always, attDegreeFrames; -#ifndef CR8_A_PLC_FADEOUT_TUNING - LC3_INT32 FADEOUT_IN_MS, PLC_P800_SPEECH_FADEOUT_IN_FRAMES, - PLC2_FADEOUT_IN_FRAMES, BURST_ATT_THRESH_PRE; -#endif const LC3_INT32 *TABLEQ15; -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT32 beta_mute_thr; /* time threshold in 10 ms frames to start beta - noise attenuation */ -#endif -#ifndef CR8_A_PLC_FADEOUT_TUNING - LC3_INT32 BURST_ATT_THRESH; /* start attenuate with losses in a row, also starts FADE2AVG actions */ - LC3_INT32 ATT_PER_FRAME; /* initial msuic attenuation table ptr, actually implemented in table lookup! */ - LC3_INT32 BETA_MUTE_THR; /* time threshold in 10 ms frames to start beta - noise attenuation */ -#endif UNUSED(attDegreeFrames_dbg); /* constants setup */ @@ -168,47 +123,12 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL XavgFadeinFactor = -1.0; -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (PLC2_FADEOUT_IN_MS < 0) - { - FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as basic input */ - } - else - { - FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settings */ - } -#endif - -#ifndef CR8_A_PLC_FADEOUT_TUNING - PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32)LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal value for speech */ - - PLC2_FADEOUT_IN_FRAMES = MIN(OFF_FRAMES_LIMIT, MAX(6, 3 * PLC_P800_SPEECH_FADEOUT_IN_FRAMES)); /* for PLC2 we typically maintain energy 3x longer */ - - BURST_ATT_THRESH_PRE = MIN(5, MAX(1, (1 * PLC2_FADEOUT_IN_FRAMES) / 6)); /* nominal 20-40 ms to start actual muting, will be thresh +1 */ - ATT_PER_FRAME = MIN(10, MAX(2, 2 * (6 - BURST_ATT_THRESH_PRE))); /* % we let the BURST_ATT_thresh control the initial table selection */ - BURST_ATT_THRESH = MIN(BURST_ATT_THRESH_PRE, 4); - BETA_MUTE_THR = MIN(4 + (OFF_FRAMES_LIMIT / 2) + 1, MAX(4, BURST_ATT_THRESH + 1 + (LC3_INT32)LC3_POW((LC3_FLOAT)2.0, BURST_ATT_THRESH_PRE - (LC3_FLOAT)1))); /* nominal time to start mandatory decrease of Xavg */ - -/* Initialize in the same way as done in trans_burst_ana_fx(), even though this is not really needed */ - burst_att_thresh = BURST_ATT_THRESH; - att_per_frame_idx = ATT_PER_FRAME; -#endif - - /* 10ms constants */ thresh_tr_dB = 10.0; /* dB threshold kept same as for 20ms, even though transient analysis frame size was shortened */ max_increase_grp_pow = 0; /* maximum amplification(dB) in case of onset transients, offset always deacy */ max_increase_grp_pow_lin = (LC3_FLOAT)1.0*LC3_POW((LC3_FLOAT)10.0, max_increase_grp_pow / (LC3_FLOAT)10.0)*(LC3_FLOAT)(32767.0 / 32768.0); - -#ifndef CR8_A_PLC_FADEOUT_TUNING - /* envelope setting */ - burst_att_thresh = BURST_ATT_THRESH + 1; - att_per_frame_idx = ATT_PER_FRAME - 1; -#endif - -#ifdef CR8_A_PLC_FADEOUT_TUNING if (plc_fadeout_type != 0) { i = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /*a long fading table entry in fade_scheme_tab */ @@ -221,7 +141,6 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL burst_att_thresh = fade_scheme_tab[i][1]; /* number of 1.0 frames before muting/mixing phase */ /* band gain muting may can take place earlier due to a band transient */ beta_mute_thr = fade_scheme_tab[i][2]; /* muting of Xavg contribution start when slow fadeout is over */ -#endif attDegreeFrames = 0; if (burst_len > burst_att_thresh) @@ -292,33 +211,12 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL assert(burst_len >= 2); /* states used here */ tr_dec[i] = 0; -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (PLC_FADEOUT_IN_MS > 0) -#endif { -#ifdef CR8_A_PLC_FADEOUT_TUNING assert(att_per_frame_idx >= 1 && att_per_frame_idx <= (10+2)); -#else - assert(att_per_frame_idx >= 1 && att_per_frame_idx <= 10); -#endif TABLEQ15 = POW_ATT_TABLES[att_per_frame_idx]; att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT) TABLEQ15[MIN(OFF_FRAMES_LIMIT, attDegreeFrames )] / (LC3_FLOAT)32768.0); /* Table idx 0...N-1 therefore no + 1 */ att_val[i] = att_val[i]; } -#ifndef CR8_A_PLC_FADEOUT_TUNING - else - { - - if (att_per_frame_idx == ATT_PER_FRAME) - { - att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE0[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); - } - else - { - att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE1[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); - } - } -#endif if ( (att_val[i] != 0) && (att_val[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5) ) { @@ -335,13 +233,8 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL mag_chg[i] = 0; /* for SNR measurments match in float lowest possible level to BASOP representation */ } - -#ifdef CR8_A_PLC_FADEOUT_TUNING /* note beta_mute decreased once per frame, not once per band */ if (i == 0 && burst_len > beta_mute_thr) -#else - if(burst_len > BETA_MUTE_THR) -#endif { *stPhECU_beta_mute = *stPhECU_beta_mute * (LC3_FLOAT)BETA_MUTE_FAC; } diff --git a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c index d4d8f15e20c3826e4292336c35052e8928e97e38..52bee02583081e61971ef8f5cbfe8735228da4b8 100644 --- a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c +++ b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c @@ -1,27 +1,22 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" - - - void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING , LC3_UINT8 plc_fadeout_type -#endif ) { LC3_FLOAT gr_pow_left[MAX_LGW]; @@ -47,9 +42,7 @@ void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_IN } plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg -#ifdef CR8_A_PLC_FADEOUT_TUNING , plc_fadeout_type -#endif ); diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c index 89d745543382512c6e1c01e71669034ef0d49951..d789a9df29da9f9ffaccb67e18a1d0e9e0d0a2ca 100644 --- a/lib_lc3plus/plc_tdc.c +++ b/lib_lc3plus/plc_tdc.c @@ -1,21 +1,21 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - /***************************************************************************\ * contents/description: Main function for Time domain concealment \***************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include #include "functions.h" - +#include "constants.h" static LC3_INT16 TDC_random_short(LC3_INT16 *seed); static LC3_FLOAT TDC_get_gainp(const LC3_FLOAT x[], const LC3_FLOAT y[], LC3_INT32 n); @@ -32,7 +32,7 @@ const LC3_FLOAT TDC_high_32_harm[TDC_L_FIR_HP] = {-0.0053f, -0.0037f, -0.0140f, static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out); static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n); static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n); - +static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms); const LC3_INT32 beforeNextIncArray[4][4] = {{0,0,0,1}, {0,1,0,1}, {0,1,1,1}, @@ -61,9 +61,8 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - ,LC3_UINT8 plc_fadeout_type -#endif + , LC3_UINT8 plc_fadeout_type + , LC3_FLOAT* alpha_type_2_table ) { LC3_FLOAT step, step_n; @@ -80,9 +79,7 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, LC3_FLOAT alphaPrev; LC3_FLOAT throttle; LC3_INT32 frame_dms_idx, nbLostFramesInRow_mod; -#ifdef CR9_I_INC_TDC_FADEOUT_LEN LC3_INT32 plc_fadeout_len = 0; -#endif memset(synth_mem, 0, M * sizeof(LC3_FLOAT)); memset(scratchSpace, 0, (MAX_LEN_PCM_PLC + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)); @@ -95,22 +92,16 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, nbLostFramesInRow_mod = (nbLostFramesInRow - 1) % 4; beforeNextInc = beforeNextIncArray[frame_dms_idx][nbLostFramesInRow_mod]; - nextInc = nextIncArray [frame_dms_idx][nbLostFramesInRow_mod]; + nextInc = nextIncArray [frame_dms_idx][nbLostFramesInRow_mod]; -#ifdef CR9_I_INC_TDC_FADEOUT_LEN - if (plc_fadeout_type == 1){ + if (plc_fadeout_type >= 1){ plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS; } else{ plc_fadeout_len = PLC_FADEOUT_IN_MS; } -#endif -#ifdef CR9_I_INC_TDC_FADEOUT_LEN if (nbLostCmpt_loc > plc_fadeout_len/10) -#else - if (nbLostCmpt_loc > PLC_FADEOUT_IN_MS/10) -#endif { gain_p = 0; *gain_c = 0; @@ -218,12 +209,10 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, alphaPrev = *alpha; } -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH if (plc_fadeout_type == 2){ - *alpha = LC3_POW(0.5,(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0); + *alpha = alpha_type_2_table[nbLostFramesInRow]; } else{ -#endif if (nextInc != 0) { @@ -257,14 +246,8 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, switch (frame_dms) { case 25: *alpha *= PLC34_ATTEN_FAC_025; break; -#ifdef CR9_J_SLOW_TDC_FADEOUT case 50: *alpha *= PLC34_ATTEN_FAC_025; break; -#else - case 50: *alpha *= PLC34_ATTEN_FAC_050; break; -#endif -#ifdef CR8_G_ADD_75MS case 75: *alpha *= PLC34_ATTEN_FAC_075; break; -#endif case 100: *alpha *= PLC34_ATTEN_FAC_100; break; } } @@ -273,9 +256,7 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, { gain_p = *alpha; } -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH } -#endif /*---------------------------------------------------------------* * Construct the harmonic part * * Last pitch cycle of the previous frame is repeatedly copied. * @@ -412,11 +393,7 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, *----------------------------------------------------------*/ if (beforeNextInc != 0) { -#ifdef CR9_I_INC_TDC_FADEOUT_LEN if (nbLostCmpt_loc == plc_fadeout_len/10) -#else - if (nbLostCmpt_loc == PLC_FADEOUT_IN_MS/10) -#endif { gain_h = 1; step = 1.0f/(LC3_FLOAT)N; @@ -464,13 +441,13 @@ void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, res.r = 0, res.i = 0; for (k = 0; k < n_bands; k++) { - res = cexpi((2 * M_PI * (LC3_FLOAT) (j * k)) / (LC3_FLOAT) n_bands); + res = cexpi((2 * M_PI_LC3PLUS * (LC3_FLOAT) (j * k)) / (LC3_FLOAT) n_bands); res.r = res.r * buf[k]; res.i = res.i * buf[k]; sum = cadd(sum, res); } - res = cexpi((LC3_FLOAT) j * M_PI / (2.0 * (LC3_FLOAT) n_bands)); + res = cexpi((LC3_FLOAT) j * M_PI_LC3PLUS / (2.0 * (LC3_FLOAT) n_bands)); out[j] = (sum.r * res.r - sum.i * res.i); } @@ -488,7 +465,7 @@ void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT for (i = 0; i < n_bands; i++) { - in[i] = in[i] * (1.0 - 2.0 * (*pre_emph_factor) * LC3_COS(2.0 * M_PI * (0.5 + (LC3_FLOAT) i) / (2.0 * (LC3_FLOAT) n_bands)) + (*pre_emph_factor) * (*pre_emph_factor)); + in[i] = in[i] * (1.0 - 2.0 * (*pre_emph_factor) * LC3_COS(2.0 * M_PI_LC3PLUS * (0.5 + (LC3_FLOAT) i) / (2.0 * (LC3_FLOAT) n_bands)) + (*pre_emph_factor) * (*pre_emph_factor)); } } @@ -800,3 +777,24 @@ static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out) } } +static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms) +{ + if (nbLostFramesInRow <= 3*100.0/frame_dms){ + return LC3_POW(0.95,(nbLostFramesInRow + (100.0/frame_dms) - 1) * frame_dms/100.0); + } + else { + LC3_INT32 n_shift = (nbLostFramesInRow - 3*100.0/frame_dms) * 50/frame_dms; + return LC3_POW(0.7,(n_shift + 100.0/frame_dms - 1) * frame_dms/100.0); + } +} + +LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms) +{ + LC3_FLOAT selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * 100/frame_dms; + if (selector >= nbLostFramesInRow){ + return type_2_alpha_long(nbLostFramesInRow, frame_dms); + } + else { + return LC3_POW(0.5,(nbLostFramesInRow + (100.0/frame_dms) - 1) * frame_dms/100.0); + } +} diff --git a/lib_lc3plus/plc_tdc_tdac.c b/lib_lc3plus/plc_tdc_tdac.c index 3c8e99b0e6ca847f3e70f2c642b151c59ed8878c..5aa4248bdff0d249c41e1f9f2677a37c41ebc9d9 100644 --- a/lib_lc3plus/plc_tdc_tdac.c +++ b/lib_lc3plus/plc_tdc_tdac.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processTdcTdac_fl(const LC3_FLOAT *synth_inp, const LC3_FLOAT *win, LC3_INT32 frame_length, LC3_INT32 la_zeroes, LC3_FLOAT *ola_mem) { LC3_INT32 i, L, LD2, NZ, synth_len; diff --git a/lib_lc3plus/plc_update.c b/lib_lc3plus/plc_update.c index 4ec4e86341df96511f70cfe6d94659c44ed2ba31..f45afb40624dcdc007351bdd049de499bdb42aba 100644 --- a/lib_lc3plus/plc_update.c +++ b/lib_lc3plus/plc_update.c @@ -1,16 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * -******************************************************************************/ +******************************************************************************/ #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, LC3_INT32 *nbLostCmpt, LC3_FLOAT *cum_alpha, LC3_INT32 bfi, LC3_INT32 *prevBfi, LC3_INT32 *prevprevBfi) { diff --git a/lib_lc3plus/quantize_spec.c b/lib_lc3plus/quantize_spec.c index 78d3486539caabddcd41c8bd49d61f858881130e..568dbe1fe1492a2bd14a7ce7abe58c0f8cb108cd 100644 --- a/lib_lc3plus/quantize_spec.c +++ b/lib_lc3plus/quantize_spec.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length); @@ -65,9 +65,7 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT LC3_INT lastnz = 1, nt_half; LC3_FLOAT offset = 0.375; LC3_INT32 bits, bits2; -#ifdef CR9_QUANT_SPEC_REWRITE LC3_FLOAT inv_gain; -#endif assert(target >= 0); @@ -76,34 +74,22 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt_half = nt >> 1; rateFlag = 0; c = 0; - if (hrmode) { offset = 0.5; } /* Quantization */ - -#ifdef CR9_QUANT_SPEC_REWRITE inv_gain = 1.0 / gain; -#endif for (i = 0; i < nt; i++) { if (x[i] > 0) { -#ifdef CR9_QUANT_SPEC_REWRITE xq[i] = (LC3_INT32) ( x[i] * inv_gain + offset); -#else - xq[i] = (LC3_INT32) ( x[i] / gain + offset); -#endif } else { -#ifdef CR9_QUANT_SPEC_REWRITE xq[i] = -((LC3_INT32) (-x[i] * inv_gain + offset)); -#else - xq[i] = -((LC3_INT32) (-x[i] / gain + offset)); -#endif } if (hrmode == 0) { assert(xq[i] <= 32767 && xq[i] >= -32768); diff --git a/lib_lc3plus/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c index 61880dbd0943af7612b396748127b54cd2367ada..3ab549d04b3a221233c7a2bc93495cad3725edc9 100644 --- a/lib_lc3plus/reorder_bitstream.c +++ b/lib_lc3plus/reorder_bitstream.c @@ -1,17 +1,16 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" - void processReorderBitstream_fl(LC3_UINT8* bytes, LC3_INT32 n_pccw, LC3_INT32 n_pc, LC3_INT32 b_left, LC3_INT32 len) { LC3_UINT8 bytes_local[MAX_NBYTES2]; diff --git a/lib_lc3plus/resamp12k8.c b/lib_lc3plus/resamp12k8.c index fd8caad7c03a57f5198ee189e5a2cc1dc39987f2..0909b67b9b5ff83854ca9726073502622b5ead2c 100644 --- a/lib_lc3plus/resamp12k8.c +++ b/lib_lc3plus/resamp12k8.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], @@ -31,11 +31,9 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 case 50: len_12k8 = LEN_12K8 / 2; break; -#ifdef CR8_G_ADD_75MS case 75: len_12k8 = (LEN_12K8 / 4) * 3; break; -#endif case 100: len_12k8 = LEN_12K8; break; diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c index bcd6637310b0e54e13b7260286b4827153250da7..282b7655e7224a021e4727b93291cf1e1dd1be50 100644 --- a/lib_lc3plus/residual_coding.c +++ b/lib_lc3plus/residual_coding.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits diff --git a/lib_lc3plus/residual_decoding.c b/lib_lc3plus/residual_decoding.c index 5085d999af8e6c9c40c510377c4e6b7385421d05..9970c094ba7909e664e663491485f2e24331a1d8 100644 --- a/lib_lc3plus/residual_decoding.c +++ b/lib_lc3plus/residual_decoding.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits diff --git a/lib_lc3plus/setup_com_lc3.c b/lib_lc3plus/setup_com_lc3.c index cecbfd7762fa9b3183817bcb17ebfddc66493a55..f37af56a3109e415bed3f7d2d49507c99ffa5bed 100644 --- a/lib_lc3plus/setup_com_lc3.c +++ b/lib_lc3plus/setup_com_lc3.c @@ -1,13 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - + #include "options.h" +#include "wmc_auto.h" #include "functions.h" LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c index 517a48b4921e81ae0d653be4f6f5ce9b4a3770d2..7bdbf0523da2e9867aa93f84029a261739b6384c 100644 --- a/lib_lc3plus/setup_dec_lc3.c +++ b/lib_lc3plus/setup_dec_lc3.c @@ -1,21 +1,21 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "setup_dec_lc3.h" #include "functions.h" #include #include /* if decoder is null only size is reported */ -# include "fft/iis_fft.h" +#include "fft/iis_fft.h" int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) { @@ -35,10 +35,8 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) HANDLE_IIS_FFT handle_ifft_phaseecu; LC3_FLOAT *q_old_res; -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL; LC3_INT16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0; -#endif for (ch = 0; ch < channels; ch++) { DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); @@ -63,14 +61,11 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); -#ifdef CR8_A_PLC_FADEOUT_TUNING - longterm_analysis_counter_max = plc_fadeout_param_maxlen[0]; - longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0]; - + longterm_analysis_counter_max = plc_fadeout_param_maxlen[0]; + longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0]; - plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); - plc_longterm_advc_ns = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); -#endif + plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); + plc_longterm_advc_ns = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); @@ -95,13 +90,11 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu; setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu; -#ifdef CR8_A_PLC_FADEOUT_TUNING setup->PlcAdvSetup->longterm_analysis_counter_max = longterm_analysis_counter_max; setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer; setup->PlcAdvSetup->plc_longterm_advc_tdc = plc_longterm_advc_tdc; setup->PlcAdvSetup->plc_longterm_advc_ns = plc_longterm_advc_ns; -#endif setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (CODEC_FS(samplerate) * 16) / 1000; real_fft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu)); @@ -127,11 +120,6 @@ LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, L decoder->hrmode = hrmode != 0; -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (decoder->fs_idx > 4) { - decoder->fs_idx = 5; - } -#endif decoder->channels = channels; decoder->frame_ms = 10; decoder->frame_dms = 100; @@ -163,7 +151,8 @@ LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, L void set_dec_frame_params(LC3PLUS_Dec* decoder) { int ch = 0; - + int n; + if (decoder->fs_idx == 5) { decoder->hrmode = 1; @@ -199,7 +188,6 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->yLen /= 2; decoder->bands_number = bands_number_5ms[decoder->fs_idx]; } -#ifdef CR8_G_ADD_75MS if (decoder->frame_ms == 7.5) { decoder->frame_length = (decoder->frame_length >> 2) * 3; @@ -213,7 +201,6 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; } } -# endif if (decoder->hrmode) { @@ -260,7 +247,6 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } decoder->cutoffBins = BW_cutoff_bin_all_5ms; } -#ifdef CR8_G_ADD_75MS else if (decoder->frame_ms == 7.5) { if (decoder->hrmode) @@ -273,7 +259,6 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } decoder->cutoffBins = BW_cutoff_bin_all_7_5ms; } -# endif decoder->n_bandsPLC = MIN(decoder->frame_length, 80); @@ -299,18 +284,15 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->n_bandsPLC = 60; } } -# ifdef CR8_G_ADD_75MS else if (decoder->frame_ms == 7.5) { decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_7_5ms[decoder->fs_idx]; if (decoder->fs != 32000 && decoder->fs != 96000) - if (decoder->fs != 32000) - { - decoder->n_bandsPLC = 60; - } + { + decoder->n_bandsPLC = 60; + } } -# endif assert(decoder->bands_offsetPLC); @@ -329,13 +311,11 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->imdct_laZeros = MDCT_la_zeroes_5ms[decoder->fs_idx]; decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_5ms[decoder->fs_idx]; } -#ifdef CR8_G_ADD_75MS else if (decoder->frame_ms == 7.5) { decoder->imdct_win = MDCT_WINS_7_5ms[decoder->hrmode][decoder->fs_idx]; decoder->imdct_laZeros = MDCT_la_zeroes_7_5ms[decoder->fs_idx]; decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_7_5ms[decoder->fs_idx]; } -# endif decoder->la_zeroes = decoder->imdct_laZeros; @@ -381,10 +361,8 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) setup->PlcAdvSetup->cum_fading_slow = 1; setup->PlcAdvSetup->cum_fflcAtten = 1; -#ifdef CR8_A_PLC_FADEOUT_TUNING setup->PlcAdvSetup->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1]; setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1]; -#endif if (decoder->fs_idx <= 4 && decoder->frame_dms == 100) { @@ -418,12 +396,13 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient */ setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs = 0; -#ifdef CR8_A_PLC_FADEOUT_TUNING setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag = -1; /* nonpure tone flag, -1==new calc., 0==pure, 1==nonpure */ -#endif } } } + for (n=0; n < LC3_ROUND(PLC_FADEOUT_TYPE_1_IN_MS*10/decoder->frame_dms);n++){ + decoder->alpha_type_2_table[n] = type_2_fadeout(n, decoder->frame_dms); + } } LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) @@ -443,12 +422,10 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) maxBytes = 375; minBytes = MIN_NBYTES; break; -#ifdef CR8_G_ADD_75MS case 75: maxBytes = 625; minBytes = MIN_NBYTES; break; -#endif case 100: maxBytes = 625; minBytes = MIN_NBYTES; @@ -460,7 +437,7 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) else { minBytes = MIN_NBYTES; - maxBytes = MAX_NBYTES_100; // for backward compatibility, MAX_NBYTES_100 is used for all frame lengths + maxBytes = MAX_NBYTES_100; /* for backward compatibility, MAX_NBYTES_100 is used for all frame lengths */ } channel_bytes = nBytes; @@ -493,12 +470,10 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) setup->enable_lpc_weighting = (setup->total_bits < 240); totalBits = setup->total_bits * 2 - 160; } -# ifdef CR8_G_ADD_75MS if (decoder->frame_ms == 7.5) { setup->enable_lpc_weighting = (setup->total_bits < 360); totalBits = round(setup->total_bits * 10 / 7.5); } -# endif if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0)) { setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0); diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h index 3ae6b139772945416e5976ecd110ac34e4f35add..c3d26ee8ebe8f0b9ab46380ed6d620d7577ee9d3 100644 --- a/lib_lc3plus/setup_dec_lc3.h +++ b/lib_lc3plus/setup_dec_lc3.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef SETUP_DEC_LC3_FL_H #define SETUP_DEC_LC3_FL_H #include "options.h" +#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ @@ -50,10 +50,7 @@ typedef struct { LC3_FLOAT x_fl[MAX_LEN]; LC3_FLOAT imdct_mem[MAX_LEN]; LC3_FLOAT alpha; -#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH - LC3_FLOAT rel_pitch_change; -#endif - + LC3_FLOAT rel_pitch_change; Dct4 dct4structImdct; PlcSetup PlcSetup; @@ -65,6 +62,7 @@ typedef struct { /* Constants and sampling rate derived values go in this struct */ struct LC3PLUS_Dec { + LC3_FLOAT alpha_type_2_table[PLC_FADEOUT_TYPE_1_IN_MS*10/25]; /* [80] */ DecSetup* channel_setup[MAX_CHANNELS]; const LC3_INT* W_fx; const LC3_INT* bands_offset; diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c index a7c94a44e2ef669e521040986d18ccd8740f45f1..750a97bb043fb78f7c3f3f0f6149c470dd8e233d 100644 --- a/lib_lc3plus/setup_enc_lc3.c +++ b/lib_lc3plus/setup_enc_lc3.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "setup_enc_lc3.h" #include "functions.h" #include @@ -43,11 +43,9 @@ LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels encoder->fs_idx = FS2FS_IDX(encoder->fs); encoder->frame_dms = 100; -#ifndef CR8_A_PLC_FADEOUT_TUNING if (encoder->fs_idx > 4) { encoder->fs_idx = 5; } -#endif encoder->hrmode = hrmode != 0; @@ -61,9 +59,12 @@ LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels encoder->r12k8_mem_in_len = 2 * 8 * encoder->fs / 12800; encoder->r12k8_mem_out_len = 24; - for (ch = 0; ch < encoder->channels; ch++) + if (lfe_channel_array != NULL) { - encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; + for (ch = 0; ch < encoder->channels; ch++) + { + encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; + } } encoder->bw_ctrl_active = 0; @@ -144,7 +145,6 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->attdec_damping = 0.5; encoder->attdec_hangover_thresh = 2; } -#ifdef CR8_G_ADD_75MS else if (encoder->frame_ms == 7.5) { if (encoder->hrmode) { @@ -176,7 +176,6 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->near_nyquist_index = encoder->bands_number - 4; encoder->r12k8_mem_out_len = ceil(2.0 * ((LC3_FLOAT) encoder->frame_length / 2.0 - (LC3_FLOAT) encoder->la_zeroes) * 12800.0 / (LC3_FLOAT) encoder->fs - 8.0); } -#endif else if (encoder->frame_ms == 5) { encoder->frame_length = encoder->frame_length >> 1; encoder->yLen /= 2; @@ -227,9 +226,7 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) setup = encoder->channel_setup[ch]; setup->olpa_mem_pitch = 17; -#ifdef CR9_F_PITCH_WIN_LEN_FIX setup->pitch_flag = 0; -#endif if (setup->mdctStruct.mem != NULL) { mdct_free(&setup->mdctStruct); mdct_init(&setup->mdctStruct, encoder->frame_length, encoder->frame_dms, encoder->fs_idx, encoder->hrmode); @@ -268,14 +265,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) else if (encoder->fs == 96000) {minBR = MIN_BR_50MS_96KHZ_HR;} else { return LC3PLUS_HRMODE_ERROR;} break; -#ifdef CR8_G_ADD_75MS case 75: maxBR = 500000; if (encoder->fs == 48000) {minBR = MIN_BR_075DMS_48KHZ_HR;} else if (encoder->fs == 96000) {minBR = MIN_BR_075DMS_96KHZ_HR;} else {return LC3PLUS_HRMODE_ERROR;} break; -#endif case 100: maxBR = 500000; if (encoder->fs == 48000) {minBR = MIN_BR_100MS_48KHZ_HR;} @@ -308,7 +303,6 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) default: break; } break; -#ifdef CR8_G_ADD_75MS case 75: minBR = MIN_BR_075DMS; maxBR = MAX_BR_075DMS; @@ -321,7 +315,6 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) default: break; } break; -#endif case 100: /* have additional limitations for 10ms */ minBR = MIN_BR_100DMS; @@ -442,11 +435,9 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) setup->targetBitsAri = setup->total_bits; setup->enable_lpc_weighting = setup->total_bits < 480; -#ifdef CR8_G_ADD_75MS if (encoder->frame_ms == 7.5) { setup->enable_lpc_weighting = setup->total_bits < 360; } -#endif if (encoder->frame_ms == 5) { setup->enable_lpc_weighting = setup->total_bits < 240; } @@ -492,11 +483,9 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) if (encoder->frame_ms == 5) { bitsTmp = bitsTmp * 2 - 160; } -#ifdef CR8_G_ADD_75MS if (encoder->frame_ms == 7.5) { bitsTmp = round(bitsTmp * 10 / 7.5); } -#endif if (bitsTmp < 400 + (encoder->fs_idx - 1) * 80) { setup->ltpf_enable = 1; @@ -525,14 +514,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) encoder->sns_damping = 6881.0/32768.0; } } -#ifdef CR8_G_ADD_75MS if (encoder->frame_ms == 7.5) { if (setup->total_bits > 3*4400/4) { encoder->sns_damping = 5898.0/32768.0; } } -#endif if (encoder->frame_ms == 5) { if (setup->total_bits > 4600/2) { @@ -559,12 +546,10 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits +=2; } -#ifdef CR8_G_ADD_75MS if (encoder->frame_ms == 7.5) { setup->regBits +=1; } -#endif if (encoder->frame_ms == 2.5) { setup->regBits -= 6; @@ -580,12 +565,10 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits += 0; } -#ifdef CR8_G_ADD_75MS if (encoder->frame_ms == 7.5) { setup->regBits +=2; } -#endif if (encoder->frame_ms == 10) { setup->regBits += 5; @@ -622,11 +605,6 @@ void update_enc_bandwidth(LC3PLUS_Enc* encoder, int bandwidth) { encoder->bandwidth = bandwidth; index = FS2FS_IDX(bandwidth); -#ifndef CR8_A_PLC_FADEOUT_TUNING - if (index > 4) { - index = 5; - } -#endif encoder->bw_ctrl_cutoff_bin = encoder->cutoffBins[index]; } } diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h index 43c29e12bcd73d3d9865fb4e706da2f724bc3d23..7947a0e649dc352909a54ff500c9165082f02763 100644 --- a/lib_lc3plus/setup_enc_lc3.h +++ b/lib_lc3plus/setup_enc_lc3.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef SETUP_ENC_LC3_FL_H #define SETUP_ENC_LC3_FL_H #include "options.h" +#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ @@ -23,11 +23,7 @@ typedef struct { LC3_FLOAT attdec_acc_energy; LC3_FLOAT r12k8_mem_50[2]; LC3_FLOAT r12k8_mem_in[120]; -#ifdef CR8_G_ADD_75MS LC3_FLOAT r12k8_mem_out[44]; -#else - LC3_FLOAT r12k8_mem_out[24]; -#endif LC3_FLOAT olpa_mem_s12k8[3]; LC3_FLOAT olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16]; LC3_FLOAT ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1]; @@ -49,9 +45,7 @@ typedef struct { LC3_INT tns_bits; LC3_INT targetBitsQuant; LC3_INT olpa_mem_pitch; -#ifdef CR9_F_PITCH_WIN_LEN_FIX LC3_INT pitch_flag; -#endif LC3_INT ltpf_mem_ltpf_on; LC3_INT mem_targetBits; LC3_INT mem_specBits; diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c index 586fd9ef669a4449dbd204ae2ff56365ba2767e7..d81c61c42acaf4e68a585cac3776f8284cb21980 100644 --- a/lib_lc3plus/sns_compute_scf.c +++ b/lib_lc3plus/sns_compute_scf.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx) diff --git a/lib_lc3plus/sns_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c index fea81e6be5684a180452a10b23d02e5a759a6dd4..15ae55c12a8598bba030bcdae43da4fc53315144 100644 --- a/lib_lc3plus/sns_interpolate_scf.c +++ b/lib_lc3plus/sns_interpolate_scf.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) diff --git a/lib_lc3plus/sns_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c index 3cb81aee9ce1c85bb87827f242976cc02aa62d89..96d8cdb4b604b43fb319e52a4f012a184b8989a4 100644 --- a/lib_lc3plus/sns_quantize_scf.c +++ b/lib_lc3plus/sns_quantize_scf.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses); @@ -506,17 +506,7 @@ void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) /* Gain */ /* Add stage 1 and stage 2 */ -#ifdef CR9_SIMPLIFY_LOOP for (i = 0; i < M; i++) { scf_q[i] += st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; } -#else - for (i = 0; i < M; i++) { - st2_vector_idct[i] = st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; - } - - for (i = 0; i < M; i++) { - scf_q[i] = scf_q[i] + st2_vector_idct[i]; - } -#endif } diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h index e311824b7fcf58b8c2363cb4bf9bfde23aa7494e..357531c3e89683efde5ec7e3c12d1b62774008f7 100644 --- a/lib_lc3plus/structs.h +++ b/lib_lc3plus/structs.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef STRUCTS_H #define STRUCTS_H #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "fft/iisfft.h" @@ -156,9 +156,7 @@ typedef struct { LC3_INT32 PhECU_num_plocs; HANDLE_IIS_FFT handle_fft_phaseecu; HANDLE_IIS_FFT handle_ifft_phaseecu; -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT16 PhECU_nonpure_tone_flag; /* BASOP Word16 PhECU_nonpure_tone_flag*/ -#endif } PlcPhEcuSetup; @@ -186,11 +184,7 @@ typedef struct { LC3_FLOAT scf_q_old_old[M]; PlcPhEcuSetup PlcPhEcuSetup; -#ifdef CR8_A_PLC_FADEOUT_TUNING LC3_INT16 longterm_counter_plcTdc; -# ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER - LC3_INT16 longterm_counter_plcPhaseEcu; -# endif LC3_INT16 longterm_counter_plcNsAdv; LC3_INT16 longterm_analysis_counter_max; /* Maximum longterm frames number */ LC3_INT16 longterm_analysis_counter_max_bytebuffer; /* Same as above but reduced for circular bit-buffer */ @@ -201,7 +195,6 @@ typedef struct { LC3_INT16 overall_counter; LC3_INT8 longterm_counter_byte_position; LC3_INT8 longterm_counter_bit_position; -#endif } PlcAdvSetup; #endif diff --git a/lib_lc3plus/tns_coder.c b/lib_lc3plus/tns_coder.c index e9301af9df8187d51317e49da9372a78cd6fa4bb..9e3c3f6f206cd9ea92490640072bc4a476de82d6 100644 --- a/lib_lc3plus/tns_coder.c +++ b/lib_lc3plus/tns_coder.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); @@ -192,12 +192,10 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L maxOrder = 4; nSubdivisions = 2.0; break; -#ifdef CR8_G_ADD_75MS case 75: maxOrder = 8; nSubdivisions = 3; break; -#endif case 100: maxOrder = 8; nSubdivisions = 3.0; @@ -234,7 +232,6 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L subdiv_startfreq = floor(subdiv_len * (sub - 1)) + startfreq[f] - 1; subdiv_stopfreq = floor(subdiv_len * sub) + startfreq[f] - 1; -#ifdef CR8_G_ADD_75MS if (fs == 32000 && frame_dms == 75) { if (subdiv_startfreq == 83) @@ -257,7 +254,6 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L subdiv_stopfreq = 159; } } -#endif sum = 0; for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) { diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c index f4dff52f396f21d5ec260d04fafa062aa4d6cb1b..05f8036fc4b99ed64a92e78eb44477adf60806a2 100644 --- a/lib_lc3plus/tns_decoder.c +++ b/lib_lc3plus/tns_decoder.c @@ -1,14 +1,14 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) diff --git a/lib_lc3plus/util.h b/lib_lc3plus/util.h index adf422cff6b354906980aa1c271814cf25fa36bf..410b7db44b02527da3d2123816a82ff2a264909c 100644 --- a/lib_lc3plus/util.h +++ b/lib_lc3plus/util.h @@ -1,17 +1,17 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.3 * +* ETSI TS 103 634 V1.5.1 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - #ifndef UTIL_H #define UTIL_H #include "options.h" +#include "wmc_auto.h" #include "clib.h" #include "math.h" diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index e55279c60fe8b2b0c58412ed0e708a4d1f514d5b..bd9fa49571f40864afb1e2692dc67264feda7d1f 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -182,11 +182,7 @@ static ivas_error ivas_rend_initCrend( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Encountered unsupported input config in Crend" ); } - if ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB -#ifdef SPLIT_REND_WITH_HEAD_ROT - && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM -#endif - ) + if ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" ); } @@ -1128,19 +1124,12 @@ static ivas_error ivas_er_init_handle( *------------------------------------------------------------------------*/ ivas_error ivas_rend_initCrendWrapper( -#ifdef SPLIT_REND_WITH_HEAD_ROT CREND_WRAPPER_HANDLE *pCrend, - const int16_t num_poses -#else - CREND_WRAPPER_HANDLE *pCrend -#endif -) + const int16_t num_poses ) { int16_t i; CREND_HANDLE hCrend; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif if ( pCrend == NULL ) { @@ -1155,9 +1144,7 @@ ivas_error ivas_rend_initCrendWrapper( ( *pCrend )->binaural_latency_ns = 0; ( *pCrend )->hHrtfCrend = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) -#endif { hCrend = NULL; if ( ( hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) @@ -1191,18 +1178,13 @@ ivas_error ivas_rend_initCrendWrapper( hCrend->m_fPitch = 0; hCrend->m_fRoll = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT ( *pCrend )->hCrend[pos_idx] = hCrend; -#else - ( *pCrend )->hCrend = hCrend; -#endif } return IVAS_ERR_OK; } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- * ivas_rend_openMultiBinCrend() * @@ -1216,20 +1198,8 @@ ivas_error ivas_rend_openMultiBinCrend( const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int32_t output_Fs ) { - ivas_error error; - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, NULL /* hHrtfStatistics */, output_Fs, pMultiBinPoseData->num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } - - return error; + return ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, NULL /* hHrtfStatistics */, output_Fs, pMultiBinPoseData->num_poses ); } -#endif /*------------------------------------------------------------------------- @@ -1245,30 +1215,19 @@ ivas_error ivas_rend_openCrend( RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, HRTFS_STATISTICS_HANDLE hHrtfStatistics, -#ifdef SPLIT_REND_WITH_HEAD_ROT const int32_t output_Fs, - const int16_t num_poses -#else - const int32_t output_Fs -#endif -) + const int16_t num_poses ) { int16_t i, subframe_length; int32_t max_total_ir_len; HRTFS_HANDLE hHrtf; CREND_HANDLE hCrend; ivas_error error; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif error = IVAS_ERR_OK; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_initCrendWrapper( pCrend, num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_initCrendWrapper( pCrend ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1283,15 +1242,9 @@ ivas_error ivas_rend_openCrend( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT hCrend = ( *pCrend )->hCrend[pos_idx]; -#else - hCrend = ( *pCrend )->hCrend; -#endif hHrtf = ( *pCrend )->hHrtfCrend; if ( hHrtf != NULL ) @@ -1440,11 +1393,7 @@ ivas_error ivas_rend_openCrend( ( *pCrend )->binaural_latency_ns = (int32_t) ( ( *pCrend )->hHrtfCrend->latency_s * 1000000000.f ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT ( *pCrend )->hCrend[pos_idx] = hCrend; -#else - ( *pCrend )->hCrend = hCrend; -#endif } return IVAS_ERR_OK; @@ -1458,18 +1407,11 @@ ivas_error ivas_rend_openCrend( *------------------------------------------------------------------------*/ void ivas_rend_closeCrend( -#ifdef SPLIT_REND_WITH_HEAD_ROT CREND_WRAPPER_HANDLE *pCrend, - const int16_t num_poses -#else - CREND_WRAPPER_HANDLE *pCrend -#endif -) + const int16_t num_poses ) { int16_t i; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif CREND_HANDLE hCrend; if ( pCrend == NULL || *pCrend == NULL ) @@ -1482,15 +1424,9 @@ void ivas_rend_closeCrend( ivas_hrtf_close( &( *pCrend )->hHrtfCrend ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT hCrend = ( *pCrend )->hCrend[pos_idx]; -#else - hCrend = ( *pCrend )->hCrend; -#endif if ( hCrend != NULL ) { for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) @@ -1573,11 +1509,7 @@ void ivas_rend_closeCrend( free( hCrend ); hCrend = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT ( *pCrend )->hCrend[pos_idx] = hCrend; -#else - ( *pCrend )->hCrend = hCrend; -#endif } } @@ -1588,7 +1520,6 @@ void ivas_rend_closeCrend( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- * ivas_rend_closeCldfbRend() * @@ -1610,7 +1541,6 @@ void ivas_rend_closeCldfbRend( return; } -#endif /*-----------------------------------------------------------------------------------------* @@ -1626,13 +1556,8 @@ static ivas_error ivas_rend_crendConvolver( float *pcm_in[], float *pcm_out[], const int32_t output_Fs, -#ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t i_ts, - const int16_t pos_idx -#else - const int16_t i_ts -#endif -) + const int16_t pos_idx ) { int16_t i, j, k, m; int16_t subframe_length, idx_in; @@ -1642,17 +1567,17 @@ static ivas_error ivas_rend_crendConvolver( const float *pIn; float *pFreq_buf_re, *pFreq_buf_im; float *pFreq_buf2_re, *pFreq_buf2_im; +#ifdef FIX_CREND_SIMPLIFY_CODE + float *pFreq_filt_re, *pFreq_filt_im; +#else const float *pFreq_filt_re, *pFreq_filt_im; +#endif float pOut[L_FRAME48k * 2]; float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; CREND_HANDLE hCrend; ivas_error error; -#ifdef SPLIT_REND_WITH_HEAD_ROT hCrend = pCrend->hCrend[pos_idx]; -#else - hCrend = pCrend->hCrend; -#endif if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) { @@ -1694,6 +1619,23 @@ static ivas_error ivas_rend_crendConvolver( } i = 0; +#ifdef FIX_CREND_SIMPLIFY_CODE + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + if ( pCrend->hHrtfCrend->same_inv_diffuse_weight ) + { + pFreq_buf_re = &hCrend->freq_buffer_re_diffuse[0][offset_diffuse]; + pFreq_buf_im = &hCrend->freq_buffer_im_diffuse[0][offset_diffuse]; + } + else + { + pFreq_buf_re = &hCrend->freq_buffer_re_diffuse[0][offset_diffuse]; + pFreq_buf_im = &hCrend->freq_buffer_im_diffuse[0][offset_diffuse]; + pFreq_buf2_re = &hCrend->freq_buffer_re_diffuse[1][offset_diffuse]; + pFreq_buf2_im = &hCrend->freq_buffer_im_diffuse[1][offset_diffuse]; + } + } +#endif for ( idx_in = 0; idx_in < nchan_in; idx_in++ ) { pIn = &pcm_in[idx_in][i_ts * subframe_length]; @@ -1703,8 +1645,10 @@ static ivas_error ivas_rend_crendConvolver( { if ( pCrend->hHrtfCrend->same_inv_diffuse_weight ) { +#ifndef FIX_CREND_SIMPLIFY_CODE pFreq_buf_re = &hCrend->freq_buffer_re_diffuse[0][offset_diffuse]; pFreq_buf_im = &hCrend->freq_buffer_im_diffuse[0][offset_diffuse]; +#endif pFreq_filt_re = &hCrend->freq_buffer_re[i][offset]; pFreq_filt_im = &hCrend->freq_buffer_im[i][offset]; @@ -1716,10 +1660,12 @@ static ivas_error ivas_rend_crendConvolver( } else { +#ifndef FIX_CREND_SIMPLIFY_CODE pFreq_buf_re = &hCrend->freq_buffer_re_diffuse[0][offset_diffuse]; pFreq_buf_im = &hCrend->freq_buffer_im_diffuse[0][offset_diffuse]; pFreq_buf2_re = &hCrend->freq_buffer_re_diffuse[1][offset_diffuse]; pFreq_buf2_im = &hCrend->freq_buffer_im_diffuse[1][offset_diffuse]; +#endif pFreq_filt_re = &hCrend->freq_buffer_re[i][offset]; pFreq_filt_im = &hCrend->freq_buffer_im[i][offset]; @@ -1732,11 +1678,17 @@ static ivas_error ivas_rend_crendConvolver( } } } +#ifdef FIX_CREND_SIMPLIFY_CODE + pFreq_filt_re = &hCrend->freq_buffer_re[i][offset]; + pFreq_filt_im = &hCrend->freq_buffer_im[i][offset]; + ivas_mdft( pIn, pFreq_filt_re, pFreq_filt_im, subframe_length, subframe_length ); +#else pFreq_buf_re = &hCrend->freq_buffer_re[i][offset]; pFreq_buf_im = &hCrend->freq_buffer_im[i][offset]; ivas_mdft( pIn, pFreq_buf_re, pFreq_buf_im, subframe_length, subframe_length ); +#endif i++; } } @@ -1840,11 +1792,8 @@ ivas_error ivas_rend_crendProcessSubframe( float *input_f[], /* i : transport channels */ float *output[], /* i/o: input/output audio channels */ const int16_t n_samples_to_render, /* i : output frame length per channel */ - const int32_t output_Fs /* i : output sampling rate */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - const int16_t pos_idx -#endif + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t pos_idx /* i : pose index */ ) { int16_t subframe_idx, subframe_len; @@ -1857,11 +1806,7 @@ ivas_error ivas_rend_crendProcessSubframe( int8_t combinedOrientationEnabled; CREND_HANDLE hCrend; -#ifdef SPLIT_REND_WITH_HEAD_ROT hCrend = pCrend->hCrend[pos_idx]; -#else - hCrend = pCrend->hCrend; -#endif combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) @@ -1956,17 +1901,11 @@ ivas_error ivas_rend_crendProcessSubframe( if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0, pos_idx ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0 ) ) != IVAS_ERR_OK ) - -#endif { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( pCrend->hCrend[0]->hReverb != NULL ) { if ( ( error = ivas_reverb_process( pCrend->hCrend[pos_idx]->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) @@ -1974,15 +1913,6 @@ ivas_error ivas_rend_crendProcessSubframe( return error; } } -#else - if ( pCrend->hCrend->hReverb != NULL ) - { - if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#endif for ( ch = 0; ch < nchan_in; ch++ ) { @@ -2024,151 +1954,6 @@ ivas_error ivas_rend_crendProcessSubframe( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-----------------------------------------------------------------------------------------* - * Function ivas_rend_crend_ProcessSplitBin() - * - * Process call for IVAS Crend renderer - *-----------------------------------------------------------------------------------------*/ - -ivas_error ivas_rend_crendProcessSplitBin( - const CREND_WRAPPER *pCrend, - const AUDIO_CONFIG inConfig, - const AUDIO_CONFIG outConfig, - const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, - EFAP_HANDLE hEFAPdata, - float *output[], - const int32_t output_Fs ) -{ - int16_t i, j; - int16_t sf; - int16_t pos_idx, output_frame; - ivas_error error; - float gain_lfe; - float tmpLfeBuffer[L_FRAME48k]; - float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; - float tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; - COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; - - output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - - /* copy input */ - for ( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) - { - mvr2r( output[i], tmpInputBuffer[i], output_frame ); - } - - for ( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) - { - p_tmpInputBuffer[i] = tmpInputBuffer[i]; - } - - /* save current head positions */ - pCombinedOrientationDataLocal = hCombinedOrientationData; - combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) - { - combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; - } - } - } - } - - /* copy LFE to tmpLfeBuffer and apply gain only once */ - if ( hIntSetup->num_lfe > 0 && hIntSetup->index_lfe[0] != -1 ) - { - mvr2r( output[hIntSetup->index_lfe[0]], tmpLfeBuffer, output_frame ); - gain_lfe = ( ( pCrend != NULL ) && ( pCrend->hHrtfCrend != NULL ) ) ? pCrend->hHrtfCrend->gain_lfe : GAIN_LFE; - v_multc( tmpLfeBuffer, gain_lfe, tmpLfeBuffer, output_frame ); - } - else - { - set_zero( tmpLfeBuffer, output_frame ); - } - - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) - { - /* Update head positions */ - - IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; - for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) - { - Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; - Quaternions_abs.w = -3.0f; - Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ - - Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; - Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; - Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; - combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; - QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); - } - - - /* render inplace to first two channels of tmpInputBuffer */ - pCombinedOrientationDataLocal = &combinedOrientationDataLocal; - - for ( i = 0; i < 3; i++ ) - { - mvr2r( hCombinedOrientationData->Rmat_prev[pos_idx][i], pCombinedOrientationDataLocal->Rmat_prev[0][i], 3 ); - } - - if ( ( error = ivas_rend_crendProcessSubframe( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, hIntSetup, hEFAPdata, - NULL, p_tmpInputBuffer, p_tmpInputBuffer, output_frame, output_Fs, pos_idx ) ) != IVAS_ERR_OK ) - { - return error; - } - - for ( i = 0; i < 3; i++ ) - { - mvr2r( pCombinedOrientationDataLocal->Rmat_prev[0][i], hCombinedOrientationData->Rmat_prev[pos_idx][i], 3 ); - } - - for ( i = 0; i < BINAURAL_CHANNELS; ++i ) - { - /* accumulate LFE to output */ - v_add( tmpInputBuffer[i], tmpLfeBuffer, tmpInputBuffer[i], output_frame ); - - /* move to split bin output buffer */ - mvr2r( tmpInputBuffer[i], tmpSplitBinBuffer[pos_idx * BINAURAL_CHANNELS + i], output_frame ); - } - - /* overwrite rendered channels with input again for next iteration */ - for ( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) - { - mvr2r( output[i], tmpInputBuffer[i], output_frame ); - } - - /* restore original headrotation data */ - for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) - { - combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; - } - } - - /* copy split binaural rendered signals to final output */ - for ( i = 0; i < BINAURAL_CHANNELS * pMultiBinPoseData->num_poses; ++i ) - { - mvr2r( tmpSplitBinBuffer[i], output[i], output_frame ); - } - - return IVAS_ERR_OK; -} -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crend_ProcessSubframesSplitBin() * @@ -2176,10 +1961,10 @@ ivas_error ivas_rend_crendProcessSplitBin( *-----------------------------------------------------------------------------------------*/ ivas_error ivas_rend_crendProcessSubframesSplitBin( - const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ - const AUDIO_CONFIG inConfig, /* i : input audio configuration */ - const AUDIO_CONFIG outConfig, /* i : output audio configuration */ - const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ + const AUDIO_CONFIG outConfig, /* i : output audio configuration */ + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : decoder config. structure */ const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, /* i : internal setup handle */ @@ -2201,7 +1986,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; float tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; @@ -2225,7 +2009,7 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( /* save current head positions */ pCombinedOrientationDataLocal = hCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) { @@ -2326,4 +2110,3 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( return IVAS_ERR_OK; } -#endif diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 33a33cdcf3178ce4f88137870fd3fd3621d91e1a..2b0cfdc02f51c5d72445669bb7f423b02cd87850 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -98,20 +98,13 @@ static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const int16_t num_freq_bands, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); -#ifdef SPLIT_REND_WITH_HEAD_ROT -static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); -static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); -#else -static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); -#endif +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const int16_t nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); -#ifdef SPLIT_REND_WITH_HEAD_ROT static void ivas_dirac_dec_binaural_process_output( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, const int16_t subframe, float outRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float outIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float reverbRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float reverbIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decorrRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decorrIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const uint8_t recompute ); -#else -static void ivas_dirac_dec_binaural_process_output( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, const int16_t subframe ); -#endif static void adaptTransportSignalsHeadtracked( COMBINED_ORIENTATION_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, const int16_t nSlots, float Rmat[3][3] ); @@ -127,11 +120,8 @@ static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Ai static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); -#ifdef SPLIT_REND_WITH_HEAD_ROT static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ); -#else -static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe ); -#endif + /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() @@ -152,15 +142,17 @@ ivas_error ivas_dirac_dec_init_binaural_data( float binCenterFreq, tmpFloat; ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t pos_idx; + int16_t num_poses, pos_idx; + + num_poses = 1; + if ( st_ivas->hSplitBinRend != NULL ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + } - for ( pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; -#else - hDiracDecBin = st_ivas->hDiracDecBin; -#endif if ( hDiracDecBin == NULL ) { @@ -234,11 +226,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_binaural_reverb_close( &( hDiracDecBin->hReverb ) ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ -#else - if ( hDiracDecBin->hReverb == NULL ) -#endif { if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, st_ivas->hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( st_ivas->hRenderConfig->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) { @@ -269,10 +257,8 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_dirac_dec_decorr_close( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( pos_idx == 0 ) /* open decorrelator only for the main direction */ { -#endif if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) { return error; @@ -281,6 +267,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( !hDiracDecBin->useTdDecorr && !( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) { ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); + if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), &( hDiracDecBin->h_freq_domain_decorr_ap_state ), nBins, @@ -294,24 +281,18 @@ ivas_error ivas_dirac_dec_init_binaural_data( return error; } } -#ifdef SPLIT_REND_WITH_HEAD_ROT } else { hDiracDecBin->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; /* copy the flag, but the implementation re-uses the decorrelated signal */ } -#endif hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); hDiracDecBin->phHrtfParambin = phHrtfParambin; -#ifdef SPLIT_REND_WITH_HEAD_ROT st_ivas->hDiracDecBin[pos_idx] = hDiracDecBin; } -#else - st_ivas->hDiracDecBin = hDiracDecBin; -#endif /* allocate transport channels */ if ( st_ivas->hTcBuffer == NULL ) @@ -350,16 +331,13 @@ void ivas_dirac_dec_close_binaural_data( DIRAC_DEC_BIN_HANDLE *hBinaural /* i/o: decoder DirAC binaural data handle */ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif if ( hBinaural == NULL || *hBinaural == NULL ) { return; } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { if ( hBinaural[pos_idx] != NULL ) @@ -380,21 +358,6 @@ void ivas_dirac_dec_close_binaural_data( hBinaural[pos_idx] = NULL; } } -#else - if ( ( *hBinaural )->hReverb != NULL ) - { - ivas_binaural_reverb_close( &( ( *hBinaural )->hReverb ) ); - } - - ivas_td_decorr_dec_close( &( ( *hBinaural )->hTdDecorr ) ); - if ( ( *hBinaural )->h_freq_domain_decorr_ap_params != NULL ) - { - ivas_dirac_dec_decorr_close( &( *hBinaural )->h_freq_domain_decorr_ap_params, &( *hBinaural )->h_freq_domain_decorr_ap_state ); - } - - free( *hBinaural ); - *hBinaural = NULL; -#endif return; } @@ -584,7 +547,6 @@ static void ivas_dirac_dec_binaural_internal( DIFFUSE_DISTRIBUTION_DATA diffuseDistData; int16_t nBins, offsetSamples; int16_t i, j; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; float tmp_Cldfb_out_re[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; @@ -598,9 +560,6 @@ static void ivas_dirac_dec_binaural_internal( float IIReneLimiter[CLDFB_NO_CHANNELS_MAX]; hDiracDecBin = st_ivas->hDiracDecBin[0]; -#else - hDiracDecBin = st_ivas->hDiracDecBin; -#endif assert( hDiracDecBin ); hSpatParamRendCom = st_ivas->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; @@ -768,20 +727,13 @@ static void ivas_dirac_dec_binaural_internal( if ( nchan_transport == 2 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT /* in case of split rendering, determine the prototype rotation based on the main direction and use the same prototypes for the offset directions */ -#endif adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); } } -#ifndef SPLIT_REND_WITH_HEAD_ROT - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData ); -#endif - if ( config_data.ivas_format == ISM_FORMAT ) { max_band_decorr = 0; @@ -795,14 +747,11 @@ static void ivas_dirac_dec_binaural_internal( max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; } - -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, subFrameTotalEne, IIReneLimiter ); ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); -#endif + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); nchanSeparateChannels = 0; if ( config_data.separateCenterChannelRendering || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) @@ -817,14 +766,13 @@ static void ivas_dirac_dec_binaural_internal( ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + pMultiBinPoseData = NULL; + if ( st_ivas->hSplitBinRend != NULL ) + { + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; + } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) -#endif { ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im, @@ -832,10 +780,10 @@ static void ivas_dirac_dec_binaural_internal( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } } @@ -845,13 +793,9 @@ static void ivas_dirac_dec_binaural_internal( max_band_decorr, numInChannels, config_data.processReverb, subframe, NULL, NULL, reverbRe, reverbIm, decorrRe, decorrIm, 1 ); } -#else - ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); -#endif hDiracDecBin->hDiffuseDist = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) { /* quaternion-based rotation from ivas_binRenderer_internal.c:ivas_binRenderer(), but using absolute rotation instead of delta rotations */ @@ -902,630 +846,105 @@ static void ivas_dirac_dec_binaural_internal( max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im, reverbRe, reverbIm, decorrRe, decorrIm, 0 ); - /* copy from temporary buffer to the main split rendering buffer */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) - { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - } - } - - hDiracDecBin->hDiffuseDist = NULL; - } - } - } - - /* update this counter only after the last rendering of split directions */ -#endif - hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; - hSpatParamRendCom->subframes_rendered++; - - return; -} - - -static void ivas_dirac_dec_decorrelate_slot( - DIRAC_DEC_BIN_HANDLE hDiracDecBin, - const int16_t num_freq_bands, - const int16_t slot, - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float decRe[][CLDFB_NO_CHANNELS_MAX], - float decIm[][CLDFB_NO_CHANNELS_MAX] ) -{ - int16_t offset, ch, bin; - float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ - float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - float protoFrameF[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - const int16_t protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 }; - - /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = num_freq_bands * BINAURAL_CHANNELS * ch; - for ( bin = 0; bin < num_freq_bands; bin++ ) - { - protoFrameF[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; - protoFrameF[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; - } - } - - /* Decorrelate proto signal to decorrelatedFrameInterleaved */ - ivas_dirac_dec_decorr_process( num_freq_bands, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - BINAURAL_CHANNELS, - protoFrameF, - BINAURAL_CHANNELS, - protoIndexDir, - decorrelatedFrameInterleaved, - onset_filter, - hDiracDecBin->h_freq_domain_decorr_ap_params, - hDiracDecBin->h_freq_domain_decorr_ap_state ); - - /* De-interleave decorrelated signals*/ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = num_freq_bands * BINAURAL_CHANNELS * ch; - for ( bin = 0; bin < num_freq_bands; bin++ ) - { - decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; - decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; - } - } - - return; -} - - -#ifdef SPLIT_REND_WITH_HEAD_ROT -static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( - DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - const int16_t subframe, - float *subFrameTotalEne, - float *IIReneLimiter ) -{ - int16_t ch, slot, bin; - int16_t nBins; - float IIReneLimiterFactor; - float qualityBasedSmFactor; - float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; - uint8_t applyLowBitRateEQ; - IVAS_FORMAT ivas_format; - int32_t ivas_total_brate; - int16_t nchan_transport; - - ivas_format = hConfig->ivas_format; - ivas_total_brate = hConfig->ivas_total_brate; - nchan_transport = hConfig->nchan_transport; - qualityBasedSmFactor = hConfig->qualityBasedSmFactor; - qualityBasedSmFactor *= qualityBasedSmFactor; - nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ - - set_zero( hDiracDecBin->ChCrossRe, nBins ); - set_zero( hDiracDecBin->ChCrossIm, nBins ); - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - set_zero( hDiracDecBin->ChEne[ch], nBins ); - } - - /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ - applyLowBitRateEQ = 0; - if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) - { - applyLowBitRateEQ = 1; - if ( ivas_total_brate == IVAS_16k4 ) - { - for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) - { - lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin] * 0.5f + 0.5f; - } - } - else - { - for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) - { - lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin]; - } - } - } - - /* Formulate input and target covariance matrices for this subframe */ - set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); - - /* Calculate input covariance matrix */ - for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) - { - for ( bin = 0; bin < nBins; bin++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - float instEne; - - instEne = ( inRe[ch][slot][bin] * inRe[ch][slot][bin] ); - instEne += ( inIm[ch][slot][bin] * inIm[ch][slot][bin] ); - hDiracDecBin->ChEne[ch][bin] += instEne; - subFrameTotalEne[bin] += instEne; - } - hDiracDecBin->ChCrossRe[bin] += inRe[0][slot][bin] * inRe[1][slot][bin]; - hDiracDecBin->ChCrossRe[bin] += inIm[0][slot][bin] * inIm[1][slot][bin]; - hDiracDecBin->ChCrossIm[bin] += inRe[0][slot][bin] * inIm[1][slot][bin]; - hDiracDecBin->ChCrossIm[bin] -= inIm[0][slot][bin] * inRe[1][slot][bin]; - } - } - - /* Apply EQ at low bit rates */ - if ( applyLowBitRateEQ ) - { - int16_t lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1; - - for ( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) - { - subFrameTotalEne[bin] *= lowBitRateEQ[bin]; - } - for ( ; bin < nBins; bin++ ) - { - subFrameTotalEne[bin] *= lowBitRateEQ[lastEqBin]; - } - } - - if ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && nchan_transport == 2 ) - { - float tempRe, tempIm; - float subFrameSumEne[CLDFB_NO_CHANNELS_MAX]; - - v_multc( subFrameTotalEne, SBA_CARDI_TARGET_ENERGY_GAIN, subFrameTotalEne, nBins ); - - set_zero( subFrameSumEne, CLDFB_NO_CHANNELS_MAX ); - for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) - { - for ( bin = 0; bin < nBins; bin++ ) - { - tempRe = inRe[0][slot][bin] + inRe[1][slot][bin]; - tempIm = inIm[0][slot][bin] + inIm[1][slot][bin]; - subFrameSumEne[bin] += tempRe * tempRe + tempIm * tempIm; - } - } - - for ( bin = 0; bin < nBins; bin++ ) - { - subFrameTotalEne[bin] = max( subFrameTotalEne[bin], subFrameSumEne[bin] ); - } - } - - /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ - if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) - { - IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); - } - else - { - IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); - } - for ( bin = 0; bin < nBins; bin++ ) - { - float eneRatio; - - /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that - * the energy history (IIR) must not be more than double of the current frame energy. This provides more - * robust performance at energy offsets when compared to typical IIR averaging. */ - eneRatio = ( hDiracDecBin->ChEne[0][bin] + hDiracDecBin->ChEne[1][bin] ) / fmaxf( 1e-12f, ( hDiracDecBin->ChEnePrev[0][bin] + hDiracDecBin->ChEnePrev[1][bin] ) ); - IIReneLimiter[bin] = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); - - hDiracDecBin->ChCrossRe[bin] *= qualityBasedSmFactor; - hDiracDecBin->ChCrossIm[bin] *= qualityBasedSmFactor; - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hDiracDecBin->ChEne[ch][bin] *= qualityBasedSmFactor; - } - - hDiracDecBin->ChCrossRe[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossRePrev[bin]; - hDiracDecBin->ChCrossIm[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossImPrev[bin]; - - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hDiracDecBin->ChEne[ch][bin] += IIReneLimiter[bin] * hDiracDecBin->ChEnePrev[ch][bin]; - } - - /* Store energy values and coefficients for next round */ - hDiracDecBin->ChCrossRePrev[bin] = hDiracDecBin->ChCrossRe[bin]; - hDiracDecBin->ChCrossImPrev[bin] = hDiracDecBin->ChCrossIm[bin]; - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hDiracDecBin->ChEnePrev[ch][bin] = hDiracDecBin->ChEne[ch][bin]; - } - } - - return; -} - -static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( - DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, - float Rmat[3][3], - const int16_t subframe, - const int16_t isHeadtracked, - const float *subFrameTotalEne, - const float *IIReneLimiter, - const MASA_ISM_DATA_HANDLE hMasaIsmData ) -{ - int16_t ch, bin; - int16_t separateCenterChannelRendering; - int16_t nBins, idx; - float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; - float qualityBasedSmFactor; - int16_t dirac_read_idx; - PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE]; - IVAS_FORMAT ivas_format; - MC_MODE mc_mode; - int16_t gainCacheBaseIndex; - - separateCenterChannelRendering = hConfig->separateCenterChannelRendering; - ivas_format = hConfig->ivas_format; - mc_mode = hConfig->mc_mode; - qualityBasedSmFactor = hConfig->qualityBasedSmFactor; - qualityBasedSmFactor *= qualityBasedSmFactor; - nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ - - set_zero( hDiracDecBin->ChCrossReOut, nBins ); - set_zero( hDiracDecBin->ChCrossImOut, nBins ); - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - set_zero( hDiracDecBin->ChEneOut[ch], nBins ); - } - set_zero( hDiracDecBin->frameMeanDiffuseness, nBins ); - - set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); - - for ( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ ) - { - gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ - } - - dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; - - /* Determine target covariance matrix containing target binaural properties */ - for ( bin = 0; bin < nBins; bin++ ) - { - float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */ - float diffusenessValForDecorrelationReduction = 1.0f; - float diffEneValForDecorrelationReduction; - float surCoh = 0.0f, spreadCoh = 0.0f; /* Default values if spreadSurroundCoherenceApplied == false */ - float diffEne, dirEne, meanEnePerCh; - int16_t dirIndex; - - /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f. - * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the - * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match - * the early spectrum of the BRIR data, using the spectral correction data in - * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ - meanEnePerCh = hDiracDecBin->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f; - - /* Determine direct part target covariance matrix (for 1 or 2 directions) */ - for ( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) - { - int16_t aziDeg, eleDeg; - float lRealp, lImagp, rRealp, rImagp; - float lRealpTmp, lImagpTmp, rRealpTmp, rImagpTmp; - float hrtfEne[BINAURAL_CHANNELS], hrtfCrossRe, hrtfCrossIm, ratio; - uint8_t isIsmDirection = 0; - - if ( dirIndex == 0 ) /* For first of the two simultaneous directions */ - { - aziDeg = hSpatParamRendCom->azimuth[dirac_read_idx][bin]; - eleDeg = hSpatParamRendCom->elevation[dirac_read_idx][bin]; - ratio = hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin]; - spreadCoh = hSpatParamRendCom->spreadCoherence[dirac_read_idx][bin]; - gainCacheBaseIndex = 0; - } - else if ( ivas_format != MASA_ISM_FORMAT || ( ivas_format == MASA_ISM_FORMAT && dirIndex < hSpatParamRendCom->numParametricDirections ) ) /* For second of the two simultaneous directions */ - { - if ( ( ratio = hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin] ) < 0.001 ) - { - /* This touches only MASA path where second direction always has smaller ratio and - * for non-2dir it is zero. As the whole direction contribution is multiplied with - * the ratio, a very small ratio does not contribute any energy to output. Thus, - * it is better to save complexity. */ - continue; - } - aziDeg = hSpatParamRendCom->azimuth2[dirac_read_idx][bin]; - eleDeg = hSpatParamRendCom->elevation2[dirac_read_idx][bin]; - spreadCoh = hSpatParamRendCom->spreadCoherence2[dirac_read_idx][bin]; - gainCacheBaseIndex = 3; - } - else /* For object directions of MASA_ISM_FORMAT */ - { - isIsmDirection = 1; - uint16_t ismDirIndex; - ismDirIndex = dirIndex - hSpatParamRendCom->numParametricDirections; - assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" ); - if ( hMasaIsmData->ism_is_edited[ismDirIndex] ) - { - aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex]; - eleDeg = hMasaIsmData->elevation_ism_edited[ismDirIndex]; - } - else - { - aziDeg = hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx]; - eleDeg = hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx]; - } - ratio = hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin]; - spreadCoh = 0.0f; - gainCacheBaseIndex = 6 + ismDirIndex; - } - - diffuseness -= ratio; /* diffuseness = 1 - ratio1 - ratio2 */ - - if ( diffuseness < 0.0f ) - { - diffuseness = 0.0f; - } - if ( isIsmDirection ) - { - /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ - diffusenessValForDecorrelationReduction -= ratio * 0.5f; - } - else - { - diffusenessValForDecorrelationReduction -= ratio; - } - - if ( separateCenterChannelRendering ) - { - /* In masa + mono rendering mode, the center directions originate from phantom sources, so the - * spread coherence is increased */ - float aziRad, eleRad, doaVectorX, spatialAngleDeg, altSpreadCoh; - - aziRad = (float) aziDeg * PI_OVER_180; - eleRad = (float) eleDeg * PI_OVER_180; - doaVectorX = cosf( aziRad ) * cosf( eleRad ); - spatialAngleDeg = acosf( doaVectorX ) * _180_OVER_PI; - altSpreadCoh = 1.0f - ( spatialAngleDeg / 30.0f ); - spreadCoh = max( spreadCoh, altSpreadCoh ); - } - - getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked, *hDiracDecBin->phHrtfParambin ); - - if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) - { - /* Synthesizing spread coherence is not needed for stereo loudspeaker output, - * as directional sound is reproduced with two loudspeakers in any case */ - spreadCoh = 0.0f; - } - - if ( spreadCoh > 0.0f ) - { - float centerMul, sidesMul; - float hrtfEneCenter, hrtfEneSides, hrtfEneRealized, eneCorrectionFactor; - float w1, w2, w3, eq; - - hrtfEneCenter = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); - - /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. - * The following formulas determine the gains for these sources. - * spreadCoh = 0: Only panning - * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi) - * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */ - if ( spreadCoh < 0.5f ) - { - /* 0.0f < spreadCoh < 0.5f */ - sidesMul = 0.5774f * spreadCoh * 2.0f; /* sqrt(1/3) = 0.5774f */ - centerMul = 1.0f - ( spreadCoh * 2.0f ) + sidesMul; - } - else - { - /* 0.5f <= spreadCoh < 1.0f */ - centerMul = 2.0f - ( 2.0f * spreadCoh ); - sidesMul = inv_sqrt( centerMul + 2.0f ); - centerMul *= sidesMul; - } - - /* Apply the gain for the center source of the three coherent sources */ - lRealp *= centerMul; - lImagp *= centerMul; - rRealp *= centerMul; - rImagp *= centerMul; - - /* Apply the gain for the left source of the three coherent sources */ - getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked, *hDiracDecBin->phHrtfParambin ); - - hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); - lRealp += sidesMul * lRealpTmp; - lImagp += sidesMul * lImagpTmp; - rRealp += sidesMul * rRealpTmp; - rImagp += sidesMul * rImagpTmp; - - /* Apply the gain for the right source of the three coherent sources. - * -30 degrees to 330 wrapping due to internal functions. */ - getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked, *hDiracDecBin->phHrtfParambin ); - hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); - lRealp += sidesMul * lRealpTmp; - lImagp += sidesMul * lImagpTmp; - rRealp += sidesMul * rRealpTmp; - rImagp += sidesMul * rImagpTmp; - - /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */ - hrtfEneRealized = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); - eneCorrectionFactor = ( ( hrtfEneSides * sidesMul * sidesMul ) + - ( hrtfEneCenter * centerMul * centerMul ) ) / - max( 1e-12f, hrtfEneRealized ); - - /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ - if ( spreadCoh < 0.5 ) - { - w1 = 1.0f - 2.0f * spreadCoh; - w2 = 2.0f * spreadCoh; - w3 = 0.0f; - } - else - { - w1 = 0.0f; - w2 = 2.0f - 2.0f * spreadCoh; - w3 = 2.0f * spreadCoh - 1.0f; - } - - if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) ) - { - idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); - - /* Apply the target spectrum to the eneCorrectionFactor */ - if ( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */ - { - eneCorrectionFactor *= w1 * 1.0f + ( w2 + w3 ) * spreadCohEne1[idx]; - } - else - { - eneCorrectionFactor *= w1 * 1.0f + w2 * spreadCohEne05[idx] + w3 * spreadCohEne1[idx]; - } - } - - /* Equalize the spread coherent combined HRTFs */ - eq = min( 4.0f, sqrtf( eneCorrectionFactor ) ); - lRealp *= eq; - lImagp *= eq; - rRealp *= eq; - rImagp *= eq; - } - - hrtfEne[0] = ( lRealp * lRealp ) + ( lImagp * lImagp ); - hrtfEne[1] = ( rRealp * rRealp ) + ( rImagp * rImagp ); - hrtfCrossRe = ( lRealp * rRealp ) + ( lImagp * rImagp ); - hrtfCrossIm = ( -lImagp * rRealp ) + ( lRealp * rImagp ); - - /* Add direct part (1 or 2) covariance matrix */ - dirEne = ratio * meanEnePerCh; - hDiracDecBin->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/ - hDiracDecBin->ChEneOut[1][bin] += dirEne * hrtfEne[1]; - hDiracDecBin->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */ - hDiracDecBin->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */ - } - - /* Add diffuse / ambient part covariance matrix */ - diffuseness = max( 0.0f, diffuseness ); - diffEne = diffuseness * meanEnePerCh; - surCoh = hSpatParamRendCom->surroundingCoherence[dirac_read_idx][bin]; - - diffusenessValForDecorrelationReduction = max( 0.0f, diffusenessValForDecorrelationReduction ); - diffEneValForDecorrelationReduction = diffusenessValForDecorrelationReduction * meanEnePerCh; - - if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) ) - { - if ( !hDiracDecBin->renderStereoOutputInsteadOfBinaural ) - { - float spectrumModVal; - - idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); - /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */ - spectrumModVal = ( 1.0f - surCoh ) + surCoh * surCohEne[idx]; - diffEne *= spectrumModVal; - - /* Modify also the value for decorrelation reduction */ - diffEneValForDecorrelationReduction *= spectrumModVal; - } - } - hDiracDecBin->ChEneOut[0][bin] += diffEne; /* Diff ene part*/ - hDiracDecBin->ChEneOut[1][bin] += diffEne; - - if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) - { - /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */ - hDiracDecBin->ChCrossReOut[bin] += surCoh * diffEne; - } - else /* When rendering binaural, ambience has frequency dependent ICC. */ - { - if ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) - { - float diffuseFieldCoherence; - diffuseFieldCoherence = hDiracDecBin->hDiffuseDist->diffuseRatioX[bin] * hDiracDecBin->diffuseFieldCoherenceX[bin] + hDiracDecBin->hDiffuseDist->diffuseRatioY[bin] * hDiracDecBin->diffuseFieldCoherenceY[bin] + hDiracDecBin->hDiffuseDist->diffuseRatioZ[bin] * hDiracDecBin->diffuseFieldCoherenceZ[bin]; - hDiracDecBin->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; - } - else - { - hDiracDecBin->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * hDiracDecBin->diffuseFieldCoherence[bin] + surCoh ) * diffEne; + /* copy from temporary buffer to the main split rendering buffer */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) + { + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + } + } + + hDiracDecBin->hDiffuseDist = NULL; } } - - /* Store parameters for formulating average diffuseness over frame */ - hDiracDecBin->frameMeanDiffuseness[bin] += diffEneValForDecorrelationReduction; - frameMeanDiffusenessEneWeight[bin] += meanEnePerCh; } - /* Formulate average diffuseness over frame */ - for ( bin = 0; bin < nBins; bin++ ) - { - hDiracDecBin->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] ); - } + /* update this counter only after the last rendering of split directions */ + hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; + hSpatParamRendCom->subframes_rendered++; - for ( bin = 0; bin < nBins; bin++ ) - { - hDiracDecBin->ChCrossReOut[bin] *= qualityBasedSmFactor; - hDiracDecBin->ChCrossImOut[bin] *= qualityBasedSmFactor; + return; +} - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hDiracDecBin->ChEneOut[ch][bin] *= qualityBasedSmFactor; - } - hDiracDecBin->ChCrossReOut[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossReOutPrev[bin]; - hDiracDecBin->ChCrossImOut[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossImOutPrev[bin]; +static void ivas_dirac_dec_decorrelate_slot( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + const int16_t num_freq_bands, + const int16_t slot, + float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float decRe[][CLDFB_NO_CHANNELS_MAX], + float decIm[][CLDFB_NO_CHANNELS_MAX] ) +{ + int16_t offset, ch, bin; + float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ + float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + float protoFrameF[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + const int16_t protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 }; - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < num_freq_bands; bin++ ) { - hDiracDecBin->ChEneOut[ch][bin] += IIReneLimiter[bin] * hDiracDecBin->ChEneOutPrev[ch][bin]; + protoFrameF[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; + protoFrameF[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; } + } - /* Store energy values and coefficients for next round */ - hDiracDecBin->ChCrossReOutPrev[bin] = hDiracDecBin->ChCrossReOut[bin]; - hDiracDecBin->ChCrossImOutPrev[bin] = hDiracDecBin->ChCrossImOut[bin]; + /* Decorrelate proto signal to decorrelatedFrameInterleaved */ + ivas_dirac_dec_decorr_process( num_freq_bands, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + BINAURAL_CHANNELS, + protoFrameF, + BINAURAL_CHANNELS, + protoIndexDir, + decorrelatedFrameInterleaved, + onset_filter, + hDiracDecBin->h_freq_domain_decorr_ap_params, + hDiracDecBin->h_freq_domain_decorr_ap_state ); - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + /* De-interleave decorrelated signals*/ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < num_freq_bands; bin++ ) { - hDiracDecBin->ChEneOutPrev[ch][bin] = hDiracDecBin->ChEneOut[ch][bin]; + decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; + decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; } } return; } -#else -static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( + + +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float Rmat[3][3], const int16_t subframe, - const int16_t isHeadtracked, - const MASA_ISM_DATA_HANDLE hMasaIsmData ) + float *subFrameTotalEne, + float *IIReneLimiter ) { int16_t ch, slot, bin; - int16_t separateCenterChannelRendering; - int16_t nBins, idx; - float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; + int16_t nBins; float IIReneLimiterFactor; float qualityBasedSmFactor; float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; uint8_t applyLowBitRateEQ; - int16_t dirac_read_idx; - float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; - PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE]; IVAS_FORMAT ivas_format; - MC_MODE mc_mode; int32_t ivas_total_brate; int16_t nchan_transport; - int16_t gainCacheBaseIndex; - separateCenterChannelRendering = hConfig->separateCenterChannelRendering; ivas_format = hConfig->ivas_format; - mc_mode = hConfig->mc_mode; ivas_total_brate = hConfig->ivas_total_brate; nchan_transport = hConfig->nchan_transport; qualityBasedSmFactor = hConfig->qualityBasedSmFactor; @@ -1534,20 +953,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric set_zero( hDiracDecBin->ChCrossRe, nBins ); set_zero( hDiracDecBin->ChCrossIm, nBins ); - set_zero( hDiracDecBin->ChCrossReOut, nBins ); - set_zero( hDiracDecBin->ChCrossImOut, nBins ); for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { set_zero( hDiracDecBin->ChEne[ch], nBins ); - set_zero( hDiracDecBin->ChEneOut[ch], nBins ); - } - set_zero( hDiracDecBin->frameMeanDiffuseness, nBins ); - - set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); - - for ( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ ) - { - gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ } /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ @@ -1573,7 +981,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Formulate input and target covariance matrices for this subframe */ set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); - dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; /* Calculate input covariance matrix */ for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) @@ -1628,12 +1035,106 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric subFrameSumEne[bin] += tempRe * tempRe + tempIm * tempIm; } } + for ( bin = 0; bin < nBins; bin++ ) { subFrameTotalEne[bin] = max( subFrameTotalEne[bin], subFrameSumEne[bin] ); } } + /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ + if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); + } + else + { + IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); + } + for ( bin = 0; bin < nBins; bin++ ) + { + float eneRatio; + + /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that + * the energy history (IIR) must not be more than double of the current frame energy. This provides more + * robust performance at energy offsets when compared to typical IIR averaging. */ + eneRatio = ( hDiracDecBin->ChEne[0][bin] + hDiracDecBin->ChEne[1][bin] ) / fmaxf( 1e-12f, ( hDiracDecBin->ChEnePrev[0][bin] + hDiracDecBin->ChEnePrev[1][bin] ) ); + IIReneLimiter[bin] = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); + + hDiracDecBin->ChCrossRe[bin] *= qualityBasedSmFactor; + hDiracDecBin->ChCrossIm[bin] *= qualityBasedSmFactor; + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEne[ch][bin] *= qualityBasedSmFactor; + } + + hDiracDecBin->ChCrossRe[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossRePrev[bin]; + hDiracDecBin->ChCrossIm[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossImPrev[bin]; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEne[ch][bin] += IIReneLimiter[bin] * hDiracDecBin->ChEnePrev[ch][bin]; + } + + /* Store energy values and coefficients for next round */ + hDiracDecBin->ChCrossRePrev[bin] = hDiracDecBin->ChCrossRe[bin]; + hDiracDecBin->ChCrossImPrev[bin] = hDiracDecBin->ChCrossIm[bin]; + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEnePrev[ch][bin] = hDiracDecBin->ChEne[ch][bin]; + } + } + + return; +} + + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, + float Rmat[3][3], + const int16_t subframe, + const int16_t isHeadtracked, + const float *subFrameTotalEne, + const float *IIReneLimiter, + const MASA_ISM_DATA_HANDLE hMasaIsmData ) +{ + int16_t ch, bin; + int16_t separateCenterChannelRendering; + int16_t nBins, idx; + float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; + float qualityBasedSmFactor; + int16_t dirac_read_idx; + PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE]; + IVAS_FORMAT ivas_format; + MC_MODE mc_mode; + int16_t gainCacheBaseIndex; + + separateCenterChannelRendering = hConfig->separateCenterChannelRendering; + ivas_format = hConfig->ivas_format; + mc_mode = hConfig->mc_mode; + qualityBasedSmFactor = hConfig->qualityBasedSmFactor; + qualityBasedSmFactor *= qualityBasedSmFactor; + nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ + + set_zero( hDiracDecBin->ChCrossReOut, nBins ); + set_zero( hDiracDecBin->ChCrossImOut, nBins ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( hDiracDecBin->ChEneOut[ch], nBins ); + } + set_zero( hDiracDecBin->frameMeanDiffuseness, nBins ); + + set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); + + for ( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ ) + { + gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ + } + + dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; + /* Determine target covariance matrix containing target binaural properties */ for ( bin = 0; bin < nBins; bin++ ) { @@ -1906,63 +1407,36 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric hDiracDecBin->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] ); } - /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ - if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) - { - IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); - } - else - { - IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); - } for ( bin = 0; bin < nBins; bin++ ) { - float eneRatio, IIReneLimiter; - - /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that - * the energy history (IIR) must not be more than double of the current frame energy. This provides more - * robust performance at energy offsets when compared to typical IIR averaging. */ - eneRatio = ( hDiracDecBin->ChEne[0][bin] + hDiracDecBin->ChEne[1][bin] ) / fmaxf( 1e-12f, ( hDiracDecBin->ChEnePrev[0][bin] + hDiracDecBin->ChEnePrev[1][bin] ) ); - IIReneLimiter = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); - - hDiracDecBin->ChCrossRe[bin] *= qualityBasedSmFactor; - hDiracDecBin->ChCrossIm[bin] *= qualityBasedSmFactor; hDiracDecBin->ChCrossReOut[bin] *= qualityBasedSmFactor; hDiracDecBin->ChCrossImOut[bin] *= qualityBasedSmFactor; for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - hDiracDecBin->ChEne[ch][bin] *= qualityBasedSmFactor; hDiracDecBin->ChEneOut[ch][bin] *= qualityBasedSmFactor; } - hDiracDecBin->ChCrossRe[bin] += IIReneLimiter * hDiracDecBin->ChCrossRePrev[bin]; - hDiracDecBin->ChCrossIm[bin] += IIReneLimiter * hDiracDecBin->ChCrossImPrev[bin]; - hDiracDecBin->ChCrossReOut[bin] += IIReneLimiter * hDiracDecBin->ChCrossReOutPrev[bin]; - hDiracDecBin->ChCrossImOut[bin] += IIReneLimiter * hDiracDecBin->ChCrossImOutPrev[bin]; + hDiracDecBin->ChCrossReOut[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossReOutPrev[bin]; + hDiracDecBin->ChCrossImOut[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossImOutPrev[bin]; for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - hDiracDecBin->ChEne[ch][bin] += IIReneLimiter * hDiracDecBin->ChEnePrev[ch][bin]; - hDiracDecBin->ChEneOut[ch][bin] += IIReneLimiter * hDiracDecBin->ChEneOutPrev[ch][bin]; + hDiracDecBin->ChEneOut[ch][bin] += IIReneLimiter[bin] * hDiracDecBin->ChEneOutPrev[ch][bin]; } /* Store energy values and coefficients for next round */ - hDiracDecBin->ChCrossRePrev[bin] = hDiracDecBin->ChCrossRe[bin]; - hDiracDecBin->ChCrossImPrev[bin] = hDiracDecBin->ChCrossIm[bin]; hDiracDecBin->ChCrossReOutPrev[bin] = hDiracDecBin->ChCrossReOut[bin]; hDiracDecBin->ChCrossImOutPrev[bin] = hDiracDecBin->ChCrossImOut[bin]; for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - hDiracDecBin->ChEnePrev[ch][bin] = hDiracDecBin->ChEne[ch][bin]; hDiracDecBin->ChEneOutPrev[ch][bin] = hDiracDecBin->ChEneOut[ch][bin]; } } return; } -#endif static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, @@ -2204,27 +1678,19 @@ static void ivas_dirac_dec_binaural_process_output( const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, - const int16_t subframe -#ifdef SPLIT_REND_WITH_HEAD_ROT - , + const int16_t subframe, float outRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float outIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float reverbRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float reverbIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decorrRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decorrIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - const uint8_t recompute -#endif -) + const uint8_t recompute ) { int16_t slot, bin, chA, chB; int16_t nBins; float outSlotRe[CLDFB_NO_CHANNELS_MAX], outSlotIm[CLDFB_NO_CHANNELS_MAX]; float decSlotRe[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; -#ifndef SPLIT_REND_WITH_HEAD_ROT - float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#endif float interpVal; float *decSlotRePointer; float *decSlotImPointer; @@ -2238,14 +1704,10 @@ static void ivas_dirac_dec_binaural_process_output( if ( processReverb ) { /* Process second / room effect part of binaural output when needed */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( recompute == 1 ) { -#endif ivas_binaural_reverb_processSubframe( hDiracDecBin->hReverb, numInChannels, nSlots, inRe, inIm, reverbRe, reverbIm ); -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } interpVal = 0.0f; @@ -2254,12 +1716,10 @@ static void ivas_dirac_dec_binaural_process_output( interpVal += 1.0f / (float) nSlots; if ( !hDiracDecBin->useTdDecorr && max_band_decorr > 0 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( recompute == 1 ) { -#endif ivas_dirac_dec_decorrelate_slot( hDiracDecBin, nBins, slot, inRe, inIm, decSlotRe, decSlotIm ); -#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { mvr2r( decSlotRe[chA], decorrRe[chA][slot], CLDFB_NO_CHANNELS_MAX ); @@ -2274,7 +1734,6 @@ static void ivas_dirac_dec_binaural_process_output( mvr2r( decorrIm[chA][slot], decSlotIm[chA], CLDFB_NO_CHANNELS_MAX ); } } -#endif } for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -2352,7 +1811,6 @@ static void ivas_dirac_dec_binaural_process_output( outSlotRePr = &( outSlotRe[0] ); outSlotImPr = &( outSlotIm[0] ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( outRe != NULL && outIm != NULL ) { /* provide the data outside in CLDFB domain => mainly for split rendering */ @@ -2364,10 +1822,6 @@ static void ivas_dirac_dec_binaural_process_output( /* Inverse filter bank */ cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); } -#else - /* Inverse filter bank */ - cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); -#endif } } @@ -3369,14 +2823,10 @@ static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], -#ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) -#else - const int16_t subframe ) -#endif { DIRAC_DEC_BIN_HANDLE hDiracDecBin; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -3390,7 +2840,6 @@ static void ivas_masa_ext_rend_parambin_internal( int16_t i, j; int16_t nchan_transport; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; float tmp_Cldfb_out_re[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; @@ -3405,9 +2854,6 @@ static void ivas_masa_ext_rend_parambin_internal( float IIReneLimiter[CLDFB_NO_CHANNELS_MAX]; hDiracDecBin = hMasaExtRend->hDiracDecBin[0]; -#else - hDiracDecBin = hMasaExtRend->hDiracDecBin; -#endif assert( hDiracDecBin ); hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; @@ -3478,9 +2924,7 @@ static void ivas_masa_ext_rend_parambin_internal( if ( nchan_transport == 2 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT /* in case of split rendering, determine the prototype rotation based on the main direction and use the same prototypes for the offset directions */ -#endif adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); @@ -3488,28 +2932,21 @@ static void ivas_masa_ext_rend_parambin_internal( } -#ifndef SPLIT_REND_WITH_HEAD_ROT - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL ); -#endif - /* Always using CLDFB decorrelation in MASA EXT renderer */ max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, subFrameTotalEne, IIReneLimiter ); + ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, subFrameTotalEne, IIReneLimiter, NULL ); -#endif ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, 0, NULL ); -#ifdef SPLIT_REND_WITH_HEAD_ROT pMultiBinPoseData = NULL; if ( hSplitRendWrapper != NULL ) { @@ -3534,13 +2971,9 @@ static void ivas_masa_ext_rend_parambin_internal( max_band_decorr, numInChannels, config_data.processReverb, subframe, NULL, NULL, reverbRe, reverbIm, decorrRe, decorrIm, 1 ); } -#else - ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); -#endif hDiracDecBin->hDiffuseDist = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) { /* quaternion-based rotation from ivas_binRenderer_internal.c:ivas_binRenderer(), but using absolute rotation instead of delta rotations */ @@ -3603,7 +3036,6 @@ static void ivas_masa_ext_rend_parambin_internal( } /* update this counter only after the last rendering of split directions */ -#endif hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; hSpatParamRendCom->subframes_rendered++; @@ -3612,17 +3044,14 @@ static void ivas_masa_ext_rend_parambin_internal( void ivas_masa_ext_rend_parambin_render( - MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const int16_t num_subframes, /* i : number of subframes to render */ - const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) /* o : rendered orientations for split rend. imag part of cldfb */ -#else - const int16_t num_subframes ) /* i : number of subframes to render */ -#endif + MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ +) { int16_t subframe; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -3643,11 +3072,7 @@ void ivas_masa_ext_rend_parambin_render( int16_t n_samples_sf = hSpatParamRendCom->slot_size * CLDFB_SLOTS_PER_SUBFRAME; hSpatParamRendCom->slots_rendered = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_masa_ext_rend_parambin_internal( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx, hSplitRendWrapper, Cldfb_Out_Real, Cldfb_Out_Imag ); -#else - ivas_masa_ext_rend_parambin_internal( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx ); -#endif for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 3caf13783fceb33c2dcd00f8a586084a275788f2..9ca3615a992fafd010dce1e52831347c03c523cd 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -38,6 +38,7 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#include "ivas_rom_rend.h" #include "ivas_stat_dec.h" #ifdef DEBUGGING #include "debug.h" @@ -51,6 +52,10 @@ #define EFAP_MAX_SIZE_TMP_BUFF 30 #define EFAP_MAX_GHOST_LS 5 /* Maximum number of ghost Loudspeakers, for memory allocation purpose */ #define POLY_THRESH 1e-4f +#ifdef DEBUG_EFAP_POLY_TOFILE +#define PANNING_AZI_RESOLUTION 2 +#define PANNING_ELE_RESOLUTION 5 +#endif /*-----------------------------------------------------------------------* @@ -147,6 +152,7 @@ ivas_error efap_init_data( ) { /* Handle instance declaration */ + int8_t polyset_size; EFAP *efap; ivas_error error; @@ -163,13 +169,13 @@ ivas_error efap_init_data( * Allocate memory *-----------------------------------------------------------------*/ - /* Memory Allocations for efap */ + /* Memory allocation for main EFAP structure */ if ( ( efap = (EFAP *) malloc( sizeof( EFAP ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP handle\n" ) ); } - /* Memory Allocation and update for aziSpk & eleSpk arrays*/ + /* Memory allocation and update for aziSpk & eleSpk arrays*/ if ( ( efap->aziSpk = (float *) malloc( num_speaker_nodes * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP speaker azimuths\n" ) ); @@ -179,7 +185,7 @@ ivas_error efap_init_data( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP speaker elevations\n" ) ); } - /* Memory Allocation for vertexArray */ + /* Memory allocation for vertexArray */ if ( ( efap->vtxData.vertexArray = (EFAP_VERTEX *) malloc( ( num_speaker_nodes + EFAP_MAX_GHOST_LS ) * sizeof( EFAP_VERTEX ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP Vertex Array\n" ) ); @@ -190,6 +196,20 @@ ivas_error efap_init_data( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP bufferS\n" ) ); } + /* get upper bound of number of polygons required */ + polyset_size = efap_poly_limit[num_speaker_nodes - 1]; + + /* Memory allocation for the polyset array */ + if ( ( efap->polyData.polysetArray = (EFAP_POLYSET *) malloc( polyset_size * sizeof( EFAP_POLYSET ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP bufferS\n" ) ); + } + + /* Memory allocation for the triangle array */ + if ( ( efap->polyData.triArray = (EFAP_LS_TRIANGLE *) malloc( polyset_size * sizeof( EFAP_LS_TRIANGLE ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP bufferS\n" ) ); + } /*-----------------------------------------------------------------* * Initialize values @@ -334,6 +354,12 @@ void efap_free_data( free( ( *hEFAPdata )->vtxData.vtxOrder ); ( *hEFAPdata )->vtxData.vtxOrder = NULL; + free( ( *hEFAPdata )->polyData.polysetArray ); + ( *hEFAPdata )->vtxData.vtxOrder = NULL; + + free( ( *hEFAPdata )->polyData.triArray ); + ( *hEFAPdata )->vtxData.vtxOrder = NULL; + free( ( *hEFAPdata )->bufferLong ); ( *hEFAPdata )->bufferLong = NULL; @@ -401,7 +427,7 @@ static ivas_error poly_init( if ( efap->vtxData.vertexArray[n].ele > 90.0 - 1e-6 || efap->vtxData.vertexArray[n].ele < 1e-6 - 90.0 ) { - efap->vtxData.vertexArray[n].isNaN = 1; + efap->vtxData.vertexArray[n].isNaN = true; } } @@ -1494,7 +1520,7 @@ static void add_vertex( vtxArray[pos].idx = (int16_t) idxAziTmp + 181 * (int16_t) idxEleTmp; /* Setting the nan flag to 0 */ - vtxArray[pos].isNaN = 0; + vtxArray[pos].isNaN = false; /* Set the default downmix type */ vtxArray[pos].dmxType = dmxType; diff --git a/lib_rend/ivas_lc3plus_enc.c b/lib_rend/ivas_lc3plus_enc.c deleted file mode 100644 index f81d912dc917e87c567e8a28deeb3639010e5df4..0000000000000000000000000000000000000000 --- a/lib_rend/ivas_lc3plus_enc.c +++ /dev/null @@ -1,334 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include "ivas_lc3plus_enc.h" -#include "ivas_lc3plus_common.h" -#include "lc3.h" -#include "ivas_error_utils.h" -#include "prot.h" -#include "wmc_auto.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_Open() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_Open( - const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ - const uint32_t bitsPerSecond, /* i : bit rate */ - IVAS_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ -) -{ - int32_t bitsPerSecondPerChannel; - int32_t encoder_size; - LC3PLUS_Error err; - int32_t lfeChans[1]; - int16_t i; - - lfeChans[0] = 0; - - if ( 0U == config.channels ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); - } - bitsPerSecondPerChannel = bitsPerSecond / config.channels; - - encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); - if ( 0 == encoder_size ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); - } - - if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - ( *handle )->pcm_conversion_buffer = NULL; - ( *handle )->num_encs = 0; - if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - for ( i = 0; i < config.channels; ++i ) - { - ( *handle )->handles[i] = NULL; - } - ( *handle )->num_encs = config.channels; - - for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) - { - if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); - } - - err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); - if ( err != LC3PLUS_OK ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); - } - - err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); - if ( err != LC3PLUS_OK ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); - } - - err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); - if ( err != LC3PLUS_OK ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); - } - } - - if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); - } - - ( *handle )->config = config; - ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); - if ( NULL == ( *handle )->pcm_conversion_buffer ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); - } - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_GetDelay() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_GetDelay( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ -) -{ - int32_t tmpDelayInSamples; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); - } - if ( NULL == delayInSamples ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); - } - - *delayInSamples = 0; - /* sanity check whether all encoders are actually configured identically */ - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) - { - if ( NULL == handle->handles[iEnc] ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); - } - - tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); - if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); - } - *delayInSamples = tmpDelayInSamples; - } - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_GetOutputBitstreamSize() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *bsSize /* o : size of each bitstream frame in bytes */ -) -{ - int32_t bitstreamSizeMultiplier; - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); - } - if ( NULL == bsSize ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); - } - - *bsSize = 0; - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) - { - if ( NULL == handle->handles[iEnc] ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); - } - *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); - } - - if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); - } - bitstreamSizeMultiplier = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; - - *bsSize *= bitstreamSizeMultiplier; - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_Close() - * - * - *-------------------------------------------------------------------*/ - -void IVAS_LC3PLUS_ENC_Close( - IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ -) -{ - if ( NULL == handle || NULL == *handle ) - { - return; - } - for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) - { - if ( NULL != ( *handle )->handles[iEnc] ) - { - lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); - free( ( *handle )->handles[iEnc] ); - } - } - if ( NULL != ( *handle )->pcm_conversion_buffer ) - { - free( ( *handle )->pcm_conversion_buffer ); - } - - free( ( *handle )->handles ); - free( *handle ); - - *handle = NULL; - - return; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_Encode() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_Encode( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - float **pcm_in, /* i : pointer input samples */ - void *bitstream_out /* o : pointer to bitstream frame */ -) -{ - uint32_t numSamplesPerLC3plusChannel; - uint32_t lc3framesPerIvasFrame; - int32_t ivasSampleIndex; - uint8_t *bitstream_out_iter = bitstream_out; - int32_t num_bytes = 0; - LC3PLUS_Error err; - - push_wmops( "IVAS_LC3PLUS_ENC_Encode" ); - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); - } - if ( NULL == pcm_in ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); - } - if ( NULL == bitstream_out ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); - } - - if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); - } - lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; - - numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame; - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) - { - for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) - { - ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; - handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); - } - - num_bytes = 0; - push_wmops( "lc3plus_enc16" ); - err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); - pop_wmops(); - if ( err != LC3PLUS_OK ) - { - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); - } - if ( 0 == num_bytes ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); - } - - bitstream_out_iter += num_bytes; - } - } - - pop_wmops(); - - return IVAS_ERR_OK; -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 35d5531633d4399761c890da105ee5bf7ecd16e4..30b0a4b3c7e68485d6890076a46652a1aaf2195b 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -36,9 +36,6 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot.h" -#endif #include #include "ivas_rom_com.h" #ifdef DEBUGGING @@ -69,6 +66,7 @@ ivas_error ivas_td_binaural_open_unwrap( const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ const AUDIO_CONFIG transport_config, /* i : Transport configuration */ const float *directivity, /* i : Directivity pattern (used for ISM) */ + const float *distAtt, /* i : Distance attenuation (used for ISM) */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ int32_t *binaural_latency_ns /* i : Binauralization delay */ @@ -82,6 +80,7 @@ ivas_error ivas_td_binaural_open_unwrap( float Pos[3]; float Dir[3]; TDREND_DirAtten_t *DirAtten_p; + TDREND_DistAtten_t DistAtten; int16_t nchan_rend; ivas_error error; @@ -187,6 +186,11 @@ ivas_error ivas_td_binaural_open_unwrap( DirAtten_p->ConeOuterAngle = 360.0f; DirAtten_p->ConeOuterGain = 1.0f; + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; + DistAtten.MaxDist = 15.75f; + DistAtten.RefDist = 1.0f; + DistAtten.RollOffFactor = 1.0f; + if ( ( error = TDREND_MIX_SRC_SetPos( pBinRendTd, nS, Pos ) ) != IVAS_ERR_OK ) { return error; @@ -206,6 +210,10 @@ ivas_error ivas_td_binaural_open_unwrap( { return error; } + if ( ( error = TDREND_MIX_SRC_SetDistAtten( pBinRendTd, nS, &DistAtten ) ) != IVAS_ERR_OK ) + { + return error; + } } } @@ -227,11 +235,28 @@ ivas_error ivas_td_binaural_open_unwrap( DirAtten_p->ConeOuterAngle = directivity[nS * 3 + 1]; DirAtten_p->ConeOuterGain = directivity[nS * 3 + 2]; } - + if ( NULL == distAtt ) + { + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; + DistAtten.MaxDist = 15.75f; + DistAtten.RefDist = 1.0f; + DistAtten.RollOffFactor = 1.0f; + } + else + { + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; + DistAtten.MaxDist = distAtt[0]; + DistAtten.RefDist = distAtt[1]; + DistAtten.RollOffFactor = distAtt[2]; + } if ( ( error = TDREND_MIX_SRC_SetDirAtten( pBinRendTd, nS, DirAtten_p ) ) != IVAS_ERR_OK ) { return error; } + if ( ( error = TDREND_MIX_SRC_SetDistAtten( pBinRendTd, nS, &DistAtten ) ) != IVAS_ERR_OK ) + { + return error; + } } } @@ -641,6 +666,7 @@ ivas_error ivas_td_binaural_open_ext( IVAS_OUTPUT_SETUP hTransSetup; ivas_error error; + float *distAtt = NULL; float *directivity = NULL; if ( inConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) @@ -670,9 +696,10 @@ ivas_error ivas_td_binaural_open_ext( if ( NULL != hRendCfg ) { directivity = hRendCfg->directivity; + distAtt = hRendCfg->distAtt; } - return ivas_td_binaural_open_unwrap( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns ); + return ivas_td_binaural_open_unwrap( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity, distAtt, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns ); } @@ -762,153 +789,6 @@ ivas_error ivas_td_binaural_renderer_ext( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*---------------------------------------------------------------------* - * ObjRenderIvasFrame_splitBinaural() - * - * Render to multiple binaural pairs based on relative head positions for split rendering. - *---------------------------------------------------------------------*/ - -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t i; - float tmpProcessing[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpBinaural[MAX_HEAD_ROT_POSES * 2][L_FRAME48k]; - float *p_tmpProcessing[MAX_OUTPUT_CHANNELS]; - int16_t pos_idx; - IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; - BINAURAL_TD_OBJECT_RENDERER_HANDLE tmpTdRendHandle; - ivas_error error; - - push_wmops( "ObjRenderIvasFrame_splitBinaural" ); - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; - - /* If not yet allocated, open additional instances of TD renderer */ - for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) - { - if ( st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i] != NULL ) - { - continue; - } - - if ( ( error = ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, - st_ivas->hDecoderConfig->output_Fs, - st_ivas->nchan_transport, - st_ivas->ivas_format, - st_ivas->transport_config, - st_ivas->hRenderConfig->directivity, - st_ivas->hTransSetup, - &st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i], - &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* Save current head positions */ - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; - } - - /* Copy input audio to a processing buffer. Cannot render in-place because binaurally rendered - * audio would overwrite original material, which is still needed for rendering next head pose. */ - for ( i = 0; i < st_ivas->nchan_transport; ++i ) - { - mvr2r( output[i], tmpProcessing[i], output_frame ); - } - - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) - { - /* Update head positions */ - if ( pos_idx != 0 ) - { - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - if ( originalHeadRot[i].w == -3.0f ) - { - st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; - st_ivas->hCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; - st_ivas->hCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; - st_ivas->hCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; - } - else - { - st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; - - Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/ - &st_ivas->hCombinedOrientationData->Quaternions[i].z, - &st_ivas->hCombinedOrientationData->Quaternions[i].y, - &st_ivas->hCombinedOrientationData->Quaternions[i].x ); - - st_ivas->hCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; - st_ivas->hCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; - st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; - } - } - } - - /* Handle the 1 ISM case where there is only one channel in the input buffer */ - for ( i = 0; i < max( st_ivas->nchan_transport, BINAURAL_CHANNELS ); ++i ) - { - p_tmpProcessing[i] = tmpProcessing[i]; - } - - /* Render */ - if ( pos_idx == 0 ) - { - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - /* Tmp swap renderer handles for rendering call */ - tmpTdRendHandle = st_ivas->hBinRendererTd; - st_ivas->hBinRendererTd = st_ivas->hSplitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; - - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - st_ivas->hBinRendererTd = tmpTdRendHandle; - } - - /* Copy rendered audio to tmp storage buffer. Copying directly to output would - * overwrite original audio, which is still needed for rendering next head pose. */ - mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); - mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); - - /* Overwrite first 2 channels with original input audio again */ - mvr2r( output[0], tmpProcessing[0], output_frame ); - mvr2r( output[1], tmpProcessing[1], output_frame ); - } - - /* Copy from storage buffer to output */ - for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; ++i ) - { - mvr2r( tmpBinaural[i], output[i], output_frame ); - } - - /* Restore original head rotation */ - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; - } - - pop_wmops(); - return IVAS_ERR_OK; -} -#endif - - /*---------------------------------------------------------------------* * angles_to_vec() * diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index ca828de2e70dbd8d30cb2dba64a35287533aac72..5f1a49ed966b64edcdd52ddc0c032aaab318741c 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -39,6 +39,7 @@ #include "wmc_auto.h" #include "ivas_rom_rend.h" #include "ivas_rom_binaural_crend_head.h" +#include #ifdef DEBUGGING #include "debug.h" #endif @@ -386,6 +387,7 @@ static ivas_error DefaultBSplineModel( ModelParamsITD_t *modelITD; int16_t i, j; ivas_error error; + float azimSegSamples; HrFiltSet_p->FilterMethod = TDREND_HRFILT_Method_BSplineModel; model = &( HrFiltSet_p->ModelParams ); @@ -396,23 +398,13 @@ static ivas_error DefaultBSplineModel( model->modelROM = TRUE; /* int16_t parameters */ - model->UseItdModel = 1; - model->SplineDegree = 4; - model->elevDim2 = 17; - model->elevDim3 = 15; - model->AlphaN = 470; - model->num_unique_azim_splines = 1; - model->elevSegSamples = 4; - model->elevBsLen[0] = 5; - model->elevBsLen[1] = 9; - model->elevBsLen[2] = 13; - model->elevBsLen[3] = 9; - model->elevBsStart[0] = 0; - model->elevBsStart[1] = 5; - model->elevBsStart[2] = 14; - model->elevBsStart[3] = 27; - - model->azimDim2 = defaultHRIR_rom_azimDim2; + model->UseItdModel = defaultHRIR_rom_model_configuration[0]; + model->elevDim3 = defaultHRIR_rom_model_configuration[1]; + model->AlphaN = defaultHRIR_rom_model_configuration[2]; + model->num_unique_azim_splines = defaultHRIR_rom_model_configuration[3]; + model->elevSegSamples = defaultHRIR_rom_model_configuration[4]; + model->elevBsLen = defaultHRIR_rom_elevBsLen; + model->elevBsStart = defaultHRIR_rom_elevBsStart; model->azimDim3 = defaultHRIR_rom_azimDim3; model->azim_start_idx = defaultHRIR_rom_azim_start_idx; model->azimSegSamples = defaultHRIR_rom_azimSegSamples; @@ -429,32 +421,28 @@ static ivas_error DefaultBSplineModel( } model->azimBsShape[0] = (const float *) defaultHRIR_rom_azimBsShape; - if ( ( model->azimKSeq = (float **) malloc( 18 * sizeof( float * ) ) ) == NULL ) + if ( ( model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); } - if ( ( model->azimKSeq[0] = (float *) malloc( 2 * sizeof( float * ) ) ) == NULL ) + for ( i = 0; i < model->elevDim3; i++ ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); - } - if ( ( model->azimKSeq[model->elevDim3 - 1] = (float *) malloc( 2 * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); - } - model->azimKSeq[0][0] = 0.0f; - model->azimKSeq[model->elevDim3 - 1][0] = 0.0f; - model->azimKSeq[0][1] = 360.0f; - model->azimKSeq[model->elevDim3 - 1][1] = 360.0f; - - for ( i = 1; i < model->elevDim3 - 1; i++ ) - { - if ( ( model->azimKSeq[i] = (float *) malloc( model->azimDim2[i] * sizeof( float * ) ) ) == NULL ) /* azimDim2[i] = 91, i=2..15 */ + if ( ( model->azimKSeq[i] = (float *) malloc( ( model->azimDim3[i] + 1 ) * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); } - for ( j = 0; j < model->azimDim2[i]; j++ ) + if ( model->azimShapeIdx[i] < 0 ) { - model->azimKSeq[i][j] = (float) defaultHRIR_rom_azimSegSamples[0] * j; + azimSegSamples = 360.0f; + } + else + { + azimSegSamples = defaultHRIR_rom_azimSegSamples[model->azimShapeIdx[i]]; + } + assert( azimSegSamples == 360.0f / model->azimDim3[i] ); + for ( j = 0; j < model->azimDim3[i] + 1; j++ ) + { + model->azimKSeq[i][j] = azimSegSamples * j; } } @@ -465,7 +453,7 @@ static ivas_error DefaultBSplineModel( model->AlphaR = (const float *) defaultHRIR_rom_AlphaR48; model->EL = (const float *) defaultHRIR_rom_EL48; model->ER = (const float *) defaultHRIR_rom_ER48; - model->K = 128; + model->K = defaultHRIR_rom_model_configuration[5]; if ( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor = 1.0f; @@ -476,7 +464,7 @@ static ivas_error DefaultBSplineModel( model->AlphaR = (const float *) defaultHRIR_rom_AlphaR32; model->EL = (const float *) defaultHRIR_rom_EL32; model->ER = (const float *) defaultHRIR_rom_ER32; - model->K = 86; + model->K = (int16_t) ceil( RESAMPLE_FACTOR_32_48 * defaultHRIR_rom_model_configuration[5] ); if ( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor = RESAMPLE_FACTOR_32_48; @@ -487,7 +475,7 @@ static ivas_error DefaultBSplineModel( model->AlphaR = (const float *) defaultHRIR_rom_AlphaR16; model->EL = (const float *) defaultHRIR_rom_EL16; model->ER = (const float *) defaultHRIR_rom_ER16; - model->K = 43; + model->K = (int16_t) ceilf( RESAMPLE_FACTOR_16_48 * defaultHRIR_rom_model_configuration[5] ); if ( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor = RESAMPLE_FACTOR_16_48; @@ -497,33 +485,17 @@ static ivas_error DefaultBSplineModel( break; } - modelITD->N = 4; - modelITD->elevDim2 = 20; - modelITD->elevDim3 = 18; - modelITD->azimDim2 = 41; - modelITD->azimDim3 = 41; - modelITD->elevSegSamples = 3; - modelITD->elevBsLen[0] = 4; - modelITD->elevBsLen[1] = 7; - modelITD->elevBsLen[2] = 10; - modelITD->elevBsLen[3] = 7; - modelITD->elevBsStart[0] = 0; - modelITD->elevBsStart[1] = 4; - modelITD->elevBsStart[2] = 11; - modelITD->elevBsStart[3] = 21; + modelITD->elevDim3 = defaultHRIR_rom_ITD_model_configuration[0]; + modelITD->azimDim3 = defaultHRIR_rom_ITD_model_configuration[1]; + modelITD->elevSegSamples = defaultHRIR_rom_ITD_model_configuration[2]; + modelITD->azimSegSamples = defaultHRIR_rom_ITD_model_configuration[3]; + modelITD->elevBsLen = defaultHRIR_rom_ITD_elevBsLen; + modelITD->elevBsStart = defaultHRIR_rom_ITD_elevBsStart; modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq; - modelITD->azimBsLen[0] = 11; - modelITD->azimBsLen[1] = 21; - modelITD->azimBsLen[2] = 31; - modelITD->azimBsLen[3] = 21; - modelITD->azimBsStart[0] = 0; - modelITD->azimBsStart[1] = 11; - modelITD->azimBsStart[2] = 32; - modelITD->azimBsStart[3] = 63; - - modelITD->azimSegSamples = 10; + modelITD->azimBsLen = defaultHRIR_rom_ITD_azimBsLen; + modelITD->azimBsStart = defaultHRIR_rom_ITD_azimBsStart; modelITD->azimKSeq = defaultHRIR_rom_ITD_azimKSeq; modelITD->W = (const float *) defaultHRIR_rom_ITD_W; diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 3f580df504d6c32b4135aa7cc68bed5fa0bc55c0..0633995e30637ba96694f0412814bffab09ed0f5 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -51,6 +51,8 @@ static void TDREND_SRC_SPATIAL_Init( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const T static void TDREND_SRC_SPATIAL_SetDirAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DirAtten_t *DirAtten_p ); +static void TDREND_SRC_SPATIAL_SetDistAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DistAtten_t *DistAtten_p ); + static float TDREND_SRC_SPATIAL_GetDirGain( const TDREND_DirAtten_t *DirAtten_p, const float *Front_p, const float *RelPos_p ); static float TDREND_SRC_SPATIAL_GetDistGain( const TDREND_DistAtten_t *DistAtten_p, const float Dist ); @@ -153,6 +155,31 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( return IVAS_ERR_OK; } +/*-------------------------------------------------------------------* + * TDREND_MIX_SRC_SetDistAtten() + * + * Set distance attenuation for the mixer. + --------------------------------------------------------------------*/ + +ivas_error TDREND_MIX_SRC_SetDistAtten( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const TDREND_DistAtten_t *DistAtten_p /* i : Distance attenuation specifier */ +) +{ + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + if ( SrcInd > hBinRendererTd->MaxSrcInd ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) ); + } + else + { + SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; + TDREND_SRC_SPATIAL_SetDistAtten( SrcSpatial_p, DistAtten_p ); + } + + return IVAS_ERR_OK; +} /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetPlayState() @@ -483,7 +510,25 @@ static void TDREND_SRC_SPATIAL_SetDirAtten( return; } +/*-------------------------------------------------------------------* + * TDREND_SRC_SPATIAL_SetDistAtten() + * + * Sets the distance attenuation. + --------------------------------------------------------------------*/ + +static void TDREND_SRC_SPATIAL_SetDistAtten( + TDREND_SRC_SPATIAL_t *SrcSpatial_p, + const TDREND_DistAtten_t *DistAtten_p ) +{ + /* Set distance attenuation */ + SrcSpatial_p->DistAttenEnabled = TRUE; + SrcSpatial_p->DistAtten.DistAttenModel = DistAtten_p->DistAttenModel; + SrcSpatial_p->DistAtten.MaxDist = DistAtten_p->MaxDist; + SrcSpatial_p->DistAtten.RefDist = DistAtten_p->RefDist; + SrcSpatial_p->DistAtten.RollOffFactor = DistAtten_p->RollOffFactor; + return; +} /*-------------------------------------------------------------------* * TDREND_SRC_SPATIAL_GetDirGain() * @@ -557,7 +602,7 @@ static float TDREND_SRC_SPATIAL_GetDistGain( switch ( DistAtten_p->DistAttenModel ) { case TDREND_DIST_ATTEN_MODEL_INV_DIST: - DistGain = DistAtten_p->RefDist / ( DistAtten_p->RefDist + DistAtten_p->RollOffFactor * ( Dist2 - DistAtten_p->RefDist ) ); + DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); break; case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED: @@ -570,8 +615,7 @@ static float TDREND_SRC_SPATIAL_GetDistGain( { Dist2 = DistAtten_p->MaxDist; } - - DistGain = DistAtten_p->RefDist / ( DistAtten_p->RefDist + DistAtten_p->RollOffFactor * ( Dist2 - DistAtten_p->RefDist ) ); + DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); break; } diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index 0e2525adb7dab662df9fb96a63b00ad1caca824b..7a92a1a5fcae43f677e5703ae63237bfab07eed4 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -48,10 +48,8 @@ * Local constants *------------------------------------------------------------------------------------------*/ -#define OTR_UPDATE_RATE (float) FRAMES_PER_SEC /* rate of the Process() calls [Hz]; 1x per IVAS frame */ -#ifdef NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES +#define OTR_UPDATE_RATE (float) FRAMES_PER_SEC /* rate of the Process() calls [Hz]; 1x per IVAS frame */ #define COS_ONE_TENTH_DEGREE ( 0.999998476913288f ) -#endif /*------------------------------------------------------------------------------------------* * Local functions @@ -159,7 +157,6 @@ void QuaternionSlerp( const float t, IVAS_QUATERNION *const r ) { -#ifdef NONBE_FIX_1067_QUATERNIONSLERP_INACCURACIES IVAS_QUATERNION r1, r2; float phi, sinPhi, cosPhi, s1, s2; @@ -198,29 +195,6 @@ void QuaternionSlerp( r->y = ( s1 * r1.y + s2 * r2.y ) / sinPhi; r->z = ( s1 * r1.z + s2 * r2.z ) / sinPhi; } -#else - float angle, denom, s, s2; - - s = QuaternionDotProduct( q1, q2 ); - - if ( fabsf( s ) >= 1.0f ) - { - - *r = q2; - return; - } - - angle = acosf( s ); - denom = sinf( angle ); - - s = sinf( ( 1 - t ) * angle ); - s2 = sinf( t * angle ); - r->x = ( q1.x * s + q2.x * s2 ) / denom; - r->y = ( q1.y * s + q2.y * s2 ) / denom; - r->z = ( q1.z * s + q2.z * s2 ) / denom; - r->w = ( q1.w * s + q2.w * s2 ) / denom; - -#endif QuaternionNormalize( *r, r ); return; diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 5d7d4d610f7a97c68060aa17139303aa8f0a0433..2105b76c3d6372133caed036cc9e0326b745fc8a 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -92,10 +92,8 @@ int16_t audioCfg2channels( nchan_out = 8; break; case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: -#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: nchan_out = 2; @@ -223,10 +221,8 @@ void ivas_output_init( hOutSetup->is_planar_setup = 0; break; case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: -#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_ISM1: @@ -323,11 +319,7 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif { nchan_out_buff = 2 * CPE_CHANNELS; } @@ -408,19 +400,17 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); } - else + else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); } } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); + nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); } -#endif return nchan_out_buff; } @@ -462,3 +452,27 @@ ivas_error ivas_output_buff_dec( return IVAS_ERR_OK; } + + +/*---------------------------------------------------------------------* + * is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ + +/*! r: flag to indicate if split rendering is enabled */ +int16_t is_split_rendering_enabled( + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* i : Render config data structure */ +) +{ + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && hDecoderConfig->Opt_non_diegetic_pan && hRenderConfig->split_rend_config.dof == 0 ) ) + { + return 1; + } + else + { + return 0; + } +} diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 7de4ed3e8cdc05d65c964f100061f33b45b5cad5..6e27b0d29b1581db8e9966cdf457a4937f7aad1b 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -77,37 +77,12 @@ int16_t ivas_get_nchan_buffers_dec( const int32_t ivas_total_brate /* i : total IVAS bitrate */ ); -/*----------------------------------------------------------------------------------* - * Limiter prototypes - *----------------------------------------------------------------------------------*/ - - -ivas_error ivas_limiter_open( - IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ - const int16_t num_channels, /* i : number of I/O channels */ - const int32_t sampling_rate /* i : sampling rate for processing */ +/*! r: flag to indicate if split rendering is enabled */ +int16_t is_split_rendering_enabled( + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* i : Render config data structure */ ); -void ivas_limiter_close( - IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ -); - -void ivas_limiter_dec -( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ - const int16_t num_channels, /* i : number of channels to be processed */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const int16_t BER_detect /* i : BER detect flag */ -); - -void limiter_process( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ - const float threshold, /* i : signal amplitude above which limiting starts to be applied */ - const int16_t BER_detect, /* i : BER detect flag */ - int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ -); /*----------------------------------------------------------------------------------* * TD decorr. function prototypes @@ -234,14 +209,10 @@ void ivas_masa_ext_rend_parambin_render( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ -#ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t num_subframes, /* i : number of subframes to render */ const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ -#else - const int16_t num_subframes /* i : number of subframes to render */ -#endif ); ivas_error ivas_dirac_dec_init_binaural_data( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -665,6 +636,7 @@ ivas_error ivas_td_binaural_open_unwrap( const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ const AUDIO_CONFIG transport_config, /* i : Transport configuration */ const float *directivity, /* i : Directivity pattern (used for ISM) */ + const float *distAtt, /* i : Distance attenuation (used for ISM) */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ int32_t *binaural_latency_ns /* i : Binauralization delay */ @@ -753,7 +725,11 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( const int16_t SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ); - +ivas_error TDREND_MIX_SRC_SetDistAtten( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const int16_t SrcInd, /* i : Source index */ + const TDREND_DistAtten_t *DistAtten_p /* i : Distance attenuation specifier */ +); ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -898,21 +874,13 @@ ivas_error ivas_rend_openCrend( RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, HRTFS_STATISTICS_HANDLE hHrtfStatistics, -#ifdef SPLIT_REND_WITH_HEAD_ROT const int32_t output_Fs, const int16_t num_poses -#else - const int32_t output_Fs -#endif ); void ivas_rend_closeCrend( -#ifdef SPLIT_REND_WITH_HEAD_ROT - CREND_WRAPPER_HANDLE *pCrend , + CREND_WRAPPER_HANDLE *pCrend, const int16_t num_poses -#else - CREND_WRAPPER_HANDLE *pCrend -#endif ); ivas_error ivas_hrtf_init( @@ -920,12 +888,8 @@ ivas_error ivas_hrtf_init( ); ivas_error ivas_rend_initCrendWrapper( -#ifdef SPLIT_REND_WITH_HEAD_ROT CREND_WRAPPER_HANDLE *pCrend, const int16_t num_poses -#else - CREND_WRAPPER_HANDLE *pCrend -#endif ); ivas_error ivas_rend_crendProcessSubframe( @@ -940,11 +904,8 @@ ivas_error ivas_rend_crendProcessSubframe( float *input_f[], /* i : transport channels */ float *output[], /* i/o: input/output audio channels */ const int16_t n_samples_to_render, /* i : output frame length per channel */ - const int32_t output_Fs /* i : output sampling rate */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - , - const int16_t pos_idx -#endif + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t pos_idx /* i : pose index */ ); @@ -980,7 +941,7 @@ void ivas_binaural_reverb_processSubframe( ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ - const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ + const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ RENDER_CONFIG_DATA *pConfig, /* i : Reverb configuration */ const int32_t output_Fs /* i : output sampling rate */ ); @@ -1229,10 +1190,6 @@ void Euler2Quat( IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ ); -float deg2rad( - float degrees -); - float rad2deg( float radians ); @@ -1242,14 +1199,12 @@ void QuatToRotMat( float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT void Quat2EulerDegree( const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ float *yaw, /* o : yaw */ float *pitch, /* o : pitch */ float *roll /* o : roll */ ); -#endif void rotateAziEle( float azi_in, /* i : output elevation */ @@ -1428,245 +1383,6 @@ ivas_error ivas_orient_trk_Process( IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT -void ivas_set_split_rend_ht_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData -); - -/*----------------------------------------------------------------------------------* - * Split binaural renderer prototypes - *----------------------------------------------------------------------------------*/ - -void ivas_set_split_rend_ht_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData -); - -ivas_error ivas_set_split_rend_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ - uint8_t *splitRendBitsBuf -); - -void ivas_init_split_rend_handles( - SPLIT_REND_WRAPPER *hSplitRendWrapper -); - -void ivas_init_split_post_rend_handles( - SPLIT_POST_REND_WRAPPER *hSplitRendWrapper -); - -ivas_error ivas_split_renderer_open( - SPLIT_REND_WRAPPER *hSplitBinRend, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t output_Fs, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t num_subframes -); - -void ivas_split_renderer_close( - SPLIT_REND_WRAPPER *hSplitBinRend -); - -ivas_error ivas_splitBinLCLDEncOpen( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, - const int32_t iSampleRate, - const int16_t iChannels, - const int32_t iDataRate, - const int16_t iNumBlocks, - const int16_t iNumIterations -); - -void ivas_splitBinLCLDEncClose( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc -); - -void ivas_splitBinLCLDEncProcess( - BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int32_t available_bits, - IVAS_SPLIT_REND_BITS_HANDLE pBits -); - -ivas_error ivas_splitBinLCLDDecOpen( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, - const int32_t iSampleRate, - const int16_t iChannels, - const int16_t iNumBlocks, - const int16_t iNumIterations -); - -void ivas_splitBinLCLDDecClose( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec -); - -void ivas_splitBinLCLDDecProcess( - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t bfi -); - -ivas_error ivas_splitBinPreRendOpen( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs -#else - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -#endif -); - -ivas_error ivas_splitBinPostRendOpen( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs -); - -void ivas_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -void ivas_renderSplitGetMultiBinPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_SPLIT_REND_ROT_AXIS rot_axis -); - -void ivas_renderSplitUpdateNoCorrectionPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -ivas_error ivas_renderMultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_CODEC splitCodec, - int16_t codec_frame_size_ms, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t max_bands, - float *output[], - const int16_t low_res_pre_rend_rot, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t ro_md_flag -); - -void ivas_rend_CldfbSplitPreRendProcess( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - const IVAS_QUATERNION headPosition, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t target_md_bits, - const int16_t low_res_pre_rend_rot, - const int16_t ro_md_flag -); - -void ivas_rend_CldfbSplitPostRendProcess( - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_QUATERNION QuaternionPost, - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], - float output[][L_FRAME48k], - const int16_t cldfb_in_flag -); - -void ivas_splitBinPreRendClose( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend -); - -void ivas_splitBinPostRendClose( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); - -void ivas_splitBinPostRendMdDec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend -#else - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -#endif -); - -ivas_error ivas_splitBinRendPLCOpen( - SPLIT_REND_PLC_HANDLE* phSplitRendPLC -); - -void ivas_splitBinRendPLCClose( - SPLIT_REND_PLC_HANDLE* phSplitRendPLC -); - -void ivas_splitBinRendPLCsaveState( - SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations -); - -void ivas_splitBinRendPLC_xf( - SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations -); - -void ivas_splitBinRendPLC( - SPLIT_REND_PLC_HANDLE hSplitRendPLC, - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs, - const int16_t iNumBlocks, - const int16_t iNumIterations -); - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG -void ivas_log_cldfb2wav_data( - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - HANDLE_CLDFB_FILTER_BANK *cldfbSyn, - const int16_t num_chs, - const int16_t num_freq_bands, - const int32_t output_Fs, - const int16_t start_slot_idx, - const int16_t md_band_idx, - const char *filename -); -#endif - -void ivas_SplitRenderer_GetRotMd( - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ - const int16_t low_res, - const int16_t ro_md_flag -); - -void ivas_SplitRenderer_PostRenderer( - BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - const IVAS_QUATERNION Quaternion_act -); - -#endif /*----------------------------------------------------------------------------------* * Rendering & merging to MASA format @@ -1777,22 +1493,14 @@ void masaPrerendClose( ); -#ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------------------------* * Split rendering *----------------------------------------------------------------------------------*/ -/* TODO(sgi): Rework interface */ -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -); - ivas_error ivas_td_binaural_renderer_sf_splitBinaural( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[], /* i/o: SCE channels / Binaural synthesis */ - int16_t nSamplesRendered /* i : number of samples to render */ + const int16_t nSamplesRendered /* i : number of samples to render */ ); ivas_error ivas_rend_crendProcessSubframesSplitBin( @@ -1811,19 +1519,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( const int32_t output_Fs /* i : output sampling rate */ ); -ivas_error ivas_rend_crendProcessSplitBin( - const CREND_WRAPPER *pCrend, - const AUDIO_CONFIG inConfig, - const AUDIO_CONFIG outConfig, - const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, - EFAP_HANDLE hEFAPdata, - float *output[], - const int32_t output_Fs -); - ivas_error ivas_rend_openMultiBinCrend( CREND_WRAPPER_HANDLE *pCrend, const AUDIO_CONFIG inConfig, @@ -1858,126 +1553,10 @@ ivas_error ivas_rend_openCldfbRend( const int32_t output_Fs ); -void ivas_mat_mult_2by2_complex( - float in_re1[2][2], - float in_im1[2][2], - float in_re2[2][2], - float in_im2[2][2], - float out_re2[2][2], - float out_im2[2][2] -); - -void ivas_split_rend_bitstream_init( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t buf_len_bytes, uint8_t *pbuf -); - -void ivas_split_rend_huffman_dec_init_min_max_len( - ivas_split_rend_huffman_cfg_t *p_huff_cfg -); - -void ivas_split_rend_init_huff_cfg( - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); - -void set_fix_rotation_mat( - float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -void set_pose_types( - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -int16_t wrap_a( - int16_t val, - const int16_t min_val, - const int16_t max_val -); - -void ivas_SplitRenderer_getdiagdiff( - int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - const int16_t sign, - const int16_t min_val, - const int16_t max_val -); - -void ivas_split_rend_bitstream_write_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits -); - -int32_t ivas_split_rend_bitstream_read_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits -); - -int32_t get_bit( - const int32_t state, - const int32_t bit_id -); - void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend ); -int32_t ivas_get_lcld_bitrate( - const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode -); - -int32_t ivas_get_split_rend_md_target_brate( - const int32_t SplitRendBitRate, - const int16_t pcm_out_flag -); - -int32_t ivas_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms -); - -int8_t ivas_get_lc3plus_bitrate_id( - const int32_t SplitRendBitRate -); - -int32_t ivas_get_lc3plus_size_from_id( - const int8_t SplitRendBitRateId, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms -); - -ivas_error ivas_split_rend_validate_config( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t pcm_out_flag -); - -void ivas_split_rend_get_quant_params( - const int16_t num_md_bands, - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t *num_quant_strats, - int16_t *num_complex_bands -); - -ivas_error ivas_split_rend_choose_default_codec( - IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ - int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ - const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ - const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ - const int16_t num_subframes /* i : number of subframes */ -); - -#endif /* clang-format on */ diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 93b175525ec8ddc39ae6c7883e69b08d3685fd1a..dfc02119c1e1eb870dfb8e0cb2395b6e959bf177 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -131,16 +131,22 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->directivity[i * 3 + 1] = 360.0f; /* Back cone */ ( *hRenderConfig )->directivity[i * 3 + 2] = 1.0f; /* Back attenuation */ } -#ifdef SPLIT_REND_WITH_HEAD_ROT - ( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + + ( *hRenderConfig )->distAtt[0] = 15.75f; /* Default max dist */ + ( *hRenderConfig )->distAtt[1] = 1.0f; /* Default ref dist */ + ( *hRenderConfig )->distAtt[2] = 1.0f; /* Default rolloff factor */ + + /* ISAR-related parameters */ + ( *hRenderConfig )->split_rend_config.splitRendBitRate = ISAR_MAX_SPLIT_REND_BITRATE; ( *hRenderConfig )->split_rend_config.dof = 3; ( *hRenderConfig )->split_rend_config.hq_mode = 0; ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; + ( *hRenderConfig )->split_rend_config.isar_frame_size_ms = 20; ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - ( *hRenderConfig )->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - ( *hRenderConfig )->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - ( *hRenderConfig )->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT; -#endif + ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 1f791df39c484abd42569ba74715776fb8e7886d..7ea38fe2a701806c1264c5e15a01b0c015280046 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -105,9 +105,6 @@ typedef struct ivas_reverb_params_t float *pFc; /* Center frequencies for FFT filter design */ float *pRt60; /* RT60 values at these frequencies */ float *pDsr; /* DSR values at these frequencies */ - float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */ - float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */ - float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */ const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */ const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ @@ -977,7 +974,6 @@ static ivas_error setup_FDN_branches( { int16_t nr_coefs, branch_idx, channel_idx; ivas_error error; - float *pCoef_a, *pCoef_b; error = IVAS_ERR_OK; /* initialize feedback branches */ @@ -999,14 +995,6 @@ static ivas_error setup_FDN_branches( { for ( branch_idx = 0; branch_idx < pParams->nr_loops; branch_idx++ ) { - pCoef_a = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; - pCoef_b = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx]; - - if ( ( error = set_t60_filter( hReverb, branch_idx, nr_coefs, pCoef_a, pCoef_b ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = set_feedback_delay( hReverb, branch_idx, pParams->pLoop_delays[branch_idx] ) ) != IVAS_ERR_OK ) { return error; @@ -1034,7 +1022,7 @@ static ivas_error setup_FDN_branches( /*------------------------------------------------------------------------- * ivas_reverb_open() * - * Allocate and initialize Crend reverberation handle + * Allocate and initialize FDN reverberation handle *------------------------------------------------------------------------*/ ivas_error ivas_reverb_open( @@ -1045,7 +1033,9 @@ ivas_error ivas_reverb_open( ) { ivas_error error; - REVERB_HANDLE pState = NULL; + REVERB_HANDLE pState = *hReverb; + int16_t nr_coefs, branch_idx; + float *pCoef_a, *pCoef_b; int16_t bin_idx, subframe_len, output_frame, predelay_bf_len, loop_idx; ivas_reverb_params_t params; rv_fftwf_type_complex pFft_wf_filter_ch0[RV_LENGTH_NR_FC]; @@ -1063,10 +1053,13 @@ ivas_error ivas_reverb_open( predelay_bf_len = output_frame; nr_fc_input = hRenderConfig->roomAcoustics.nBands; - /* Allocate main reverb. handle */ - if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) + if ( *hReverb == NULL ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Reverberator " ); + /* Allocate main reverb. handle */ + if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator " ); + } } if ( ( error = set_base_config( ¶ms, output_Fs ) ) != IVAS_ERR_OK ) @@ -1074,34 +1067,35 @@ ivas_error ivas_reverb_open( return error; } - /* Allocate memory for feedback delay lines */ - for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) + if ( *hReverb == NULL ) { - if ( ( pState->loop_delay_buffer[loop_idx] = (float *) malloc( params.pLoop_delays[loop_idx] * sizeof( float ) ) ) == NULL ) + /* Allocate memory for feedback delay lines */ + for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CREND Reverberator" ); + if ( ( pState->loop_delay_buffer[loop_idx] = (float *) malloc( params.pLoop_delays[loop_idx] * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" ); + } } - } - /* Allocate memory for the pre-delay delay line */ - if ( ( pState->pPredelay_buffer = (float *) malloc( output_frame * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CREND Reverberator" ); + /* Allocate memory for the pre-delay delay line */ + if ( ( pState->pPredelay_buffer = (float *) malloc( output_frame * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FDN Reverberator" ); + } } pState->nr_of_branches = IVAS_REV_MAX_NR_BRANCHES; set_fft_and_datablock_sizes( pState, subframe_len ); + nr_fc_fft_filter = ( pState->fft_size >> 1 ) + 1; /* === 'Control logic': compute the reverb processing parameters from the === */ /* === room, source and listener acoustic information provided in the reverb config === */ /* Setting up shared temporary buffers for fc, RT60, DSR, etc. */ - params.pHrtf_avg_pwr_response_l = &pFft_wf_filter_ch0[0][0]; - params.pHrtf_avg_pwr_response_r = params.pHrtf_avg_pwr_response_l + nr_fc_fft_filter; params.pRt60 = &pFft_wf_filter_ch1[0][0]; params.pDsr = params.pRt60 + nr_fc_fft_filter; params.pFc = &pState->fft_filter_color_0.fft_spectrum[0]; - params.pHrtf_inter_aural_coherence = &pState->fft_filter_color_1.fft_spectrum[0]; /* Note: these temp buffers can only be used before the final step of the FFT filter design : */ /* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */ @@ -1132,7 +1126,10 @@ ivas_error ivas_reverb_open( } /* set up input downmix */ - pState->dmx_gain = calc_dmx_gain(); + if ( *hReverb == NULL ) + { + pState->dmx_gain = calc_dmx_gain(); + } /* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */ calc_predelay( ¶ms, hRenderConfig->roomAcoustics.acousticPreDelay, output_Fs ); @@ -1156,16 +1153,17 @@ ivas_error ivas_reverb_open( /* Compute the window used for FFT filters */ ivas_reverb_define_window_fft( pTime_window, transition_start, transition_length, nr_fc_fft_filter ); - - /* === Now, copy parameters from ivas_reverb_params_t into DSP blocks === */ - /* === to be used for subsequent audio signal processing === */ - - pState->do_corr_filter = params.do_corr_filter; - - /* clear & init jot reverb fft filters */ - if ( ( error = initialize_reverb_filters( pState ) ) != IVAS_ERR_OK ) + /* === Copy parameters from ivas_reverb_params_t into DSP blocks === */ + /* === to be used for subsequent audio signal processing === */ + if ( *hReverb == NULL ) { - return error; + pState->do_corr_filter = params.do_corr_filter; + + /* clear & init jot reverb fft filters */ + if ( ( error = initialize_reverb_filters( pState ) ) != IVAS_ERR_OK ) + { + return error; + } } if ( pState->do_corr_filter ) @@ -1199,13 +1197,33 @@ ivas_error ivas_reverb_open( return error; } - /* init predelay */ - ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); + if ( *hReverb == NULL ) + { + /* init predelay */ + ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); - /* set up feedback delay network */ - if ( ( error = setup_FDN_branches( pState, ¶ms ) ) != IVAS_ERR_OK ) + /* set up feedback delay network */ + if ( ( error = setup_FDN_branches( pState, ¶ms ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else { - return error; + pState->predelay_line.Delay = params.pre_delay; + } + + nr_coefs = params.t60_filter_order + 1; + + for ( branch_idx = 0; branch_idx < params.nr_loops; branch_idx++ ) + { + pCoef_a = ¶ms.pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; + pCoef_b = ¶ms.pT60_filter_coeff[2 * nr_coefs * branch_idx]; + + if ( ( error = set_t60_filter( pState, branch_idx, nr_coefs, pCoef_a, pCoef_b ) ) != IVAS_ERR_OK ) + { + return error; + } } *hReverb = pState; diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c index 2879476014732b60dd705370ceabaee7a76aff8e..9f7550fbe4fe0ada059f399cbde0457d207db307 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer.c @@ -50,8 +50,19 @@ *------------------------------------------------------------------------*/ /* TD renderer default HRIR model */ const float defaultHRIR_rom_latency_s = 0.000020834f; -const int16_t defaultHRIR_rom_azimDim2[15] = { -1, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 1, +const int16_t defaultHRIR_rom_model_configuration[6] = { +1, /* UseItdModel */ +15, /* elevDim3 */ +470, /* AlphaN */ +1, /* num_unique_azim_splines */ +4, /* elevSegSamples */ +128, /* K_48k */ +}; +const int16_t defaultHRIR_rom_elevBsLen[4] = { +5, 9, 13, 9, +}; +const int16_t defaultHRIR_rom_elevBsStart[4] = { +0, 5, 14, 27, }; const int16_t defaultHRIR_rom_azimDim3[15] = { 1, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 1, @@ -10139,6 +10150,24 @@ const uint32_t defaultHRIR_rom_ITD_W[658] = { 0x3c678a1c,0xbdeb0ba5,0xbe2218a5,0x3e58dcde,0x3d71aaa0,0xbef80fb9,0xbf3d07e1,0x3f3485be,0x3db783c0,0x3c142933,0xbed36b04,0xbb9f1f49,0x3ebfdc23,0xbcc7652e,0xbdb4e6cd,0xbf3be092,0x3f399c4e,0x3ef2eb6a,0xbd93a618,0xbe480d88,0x3e1bd187,0x3df79a5d,0xbc53f8d6,0xbf002186,0xbd41bc42, 0x3e5c0f28,0x3f2ad402,0xbf3cc2c3,0xbedc59d1,0xbe021816,0x3ea43429,0x3d349309,0xbab986b3, }; +const int16_t defaultHRIR_rom_ITD_model_configuration[4] = { +18, /* elevDim3 */ +41, /* azimDim3 */ +3, /* elevSegSamples */ +10, /* azimSegSamples */ +}; +const int16_t defaultHRIR_rom_ITD_elevBsLen[4] = { +4, 7, 10, 7, +}; +const int16_t defaultHRIR_rom_ITD_elevBsStart[4] = { +0, 4, 11, 21, +}; +const int16_t defaultHRIR_rom_ITD_azimBsLen[4] = { +11, 21, 31, 21, +}; +const int16_t defaultHRIR_rom_ITD_azimBsStart[4] = { +0, 11, 32, 63, +}; const uint32_t defaultHRIR_rom_ITD_azimBsShape[84] = { 0x3f800000,0x3f3a9fbe,0x3f03126f,0x3eaf9db2,0x3e5d2f1b,0x3e000000,0x3d83126f,0x3cdd2f1b,0x3c03126f,0x3a83126f,0xa5800000,0x00000000,0x3e8374bc,0x3ede353f,0x3f0ad0e5,0x3f178d50,0x3f180000,0x3f0ed917,0x3efd9168,0x3ed4fdf4,0x3ea95810,0x3e800000,0x3e3a9fbe,0x3e03126f,0x3daf9db2, 0x3d5d2f1b,0x3d000000,0x3c83126f,0x3bdd2f1b,0x3b03126f,0x3983126f,0xa6000000,0x00000000,0x3c66bdc8,0x3d57b901,0x3de1cac1,0x3e39af72,0x3e855555,0x3eaf1aa0,0x3ed756b3,0x3efb38a9,0x3f0bf7cf,0x3f155555,0x3f18aec3,0x3f16872b,0x3f0fc3ed,0x3f054a69,0x3ef00000,0x3ed19423,0x3eb11bfd, diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.h b/lib_rend/ivas_rom_TdBinauralRenderer.h index c79742757e5d9d401814eaea00bf0447cc1e43da..cc44aa9643c1bf18e08ad004925a3fbcdb6d08d0 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.h +++ b/lib_rend/ivas_rom_TdBinauralRenderer.h @@ -47,7 +47,7 @@ *------------------------------------------------------------------------*/ /* TD renderer default HRIR model */ extern const float defaultHRIR_rom_latency_s; -extern const int16_t defaultHRIR_rom_azimDim2[15]; +extern const int16_t defaultHRIR_rom_model_configuration[6]; extern const int16_t defaultHRIR_rom_azimDim3[15]; extern const int16_t defaultHRIR_rom_azim_start_idx[15]; extern const int16_t defaultHRIR_rom_azimSegSamples[1]; @@ -66,6 +66,8 @@ extern const uint32_t defaultHRIR_rom_EL32[HRTF_MODEL_N_SECTIONS * 470]; extern const uint32_t defaultHRIR_rom_ER32[HRTF_MODEL_N_SECTIONS * 470]; extern const uint32_t defaultHRIR_rom_EL16[HRTF_MODEL_N_SECTIONS * 470]; extern const uint32_t defaultHRIR_rom_ER16[HRTF_MODEL_N_SECTIONS * 470]; +extern const int16_t defaultHRIR_rom_elevBsLen[4]; +extern const int16_t defaultHRIR_rom_elevBsStart[4]; extern const uint32_t defaultHRIR_rom_elevBsShape[36]; extern const uint32_t defaultHRIR_rom_azimBsShape[21]; extern const uint32_t defaultHRIR_rom_ITD_W[658]; @@ -73,4 +75,9 @@ extern const uint32_t defaultHRIR_rom_ITD_azimBsShape[84]; extern const float defaultHRIR_rom_ITD_azimKSeq[19]; extern const uint32_t defaultHRIR_rom_ITD_elevBsShape[28]; extern const float defaultHRIR_rom_ITD_elevKSeq[16]; +extern const int16_t defaultHRIR_rom_ITD_model_configuration[4]; +extern const int16_t defaultHRIR_rom_ITD_elevBsLen[4]; +extern const int16_t defaultHRIR_rom_ITD_elevBsStart[4]; +extern const int16_t defaultHRIR_rom_ITD_azimBsLen[4]; +extern const int16_t defaultHRIR_rom_ITD_azimBsStart[4]; #endif diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 90a2feb86a4f0345bd215507bf8b7c2a47980684..304b7a37670c54cfc055885b27cb558c0e38023d 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -388,6 +388,11 @@ const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = const float ls_azimuth_CICP1[1] = { 0.0f }; const float ls_elevation_CICP1[1] = { 0.0f }; +/*----------------------------------------------------------------------------------* + * EFAP ROM tables + *----------------------------------------------------------------------------------*/ + +const int8_t efap_poly_limit[MAX_OUTPUT_CHANNELS] = {22, 22, 22, 26, 30, 34, 36, 42, 42, 44, 47, 51, 52, 54, 54, 54}; /*----------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index e39c43813781e3fe9274c4f99a256e00f7c676bc..aacded4d5f64c9fd426bfe59f8f55ae6932c0466 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -125,6 +125,13 @@ extern const float ls_azimuth_CICP1[1]; extern const float ls_elevation_CICP1[1]; +/*----------------------------------------------------------------------------------* + * EFAP ROM tables + *----------------------------------------------------------------------------------*/ + +extern const int8_t efap_poly_limit[MAX_OUTPUT_CHANNELS]; + + /*----------------------------------------------------------------------------------* * LS Configuration Converter ROM tables *----------------------------------------------------------------------------------*/ @@ -137,12 +144,4 @@ extern const float ls_conversion_cicpX_stereo[12][2]; extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split binaural rendering ROM tables - *----------------------------------------------------------------------------------*/ - -extern const int32_t split_rend_brate_tbl[]; -#endif - #endif /* IVAS_ROM_REND_H */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index adf6bec2262151dfd62beb7617d3e330ae3e8208..198100dfff131913fce36b743f3ba334be48a392 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -37,6 +37,7 @@ #include #include "cnst.h" #include "prot.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #ifdef DEBUGGING #include "debug.h" @@ -48,19 +49,10 @@ * Local funtion declarations *-----------------------------------------------------------------------*/ -static ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, - IVAS_VECTOR3 *listenerPos, -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ -#endif - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); -static void external_target_interpolation( - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - const int16_t i ); +static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); + +static void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const int16_t i ); static bool are_orientations_same( const IVAS_QUATERNION *orientation1, const IVAS_QUATERNION *orientation2 ); @@ -105,9 +97,7 @@ ivas_error ivas_headTrack_open( ( *hHeadTrackData )->Rmat_prev[i][i] = 1.0f; } -#ifdef SPLIT_REND_WITH_HEAD_ROT ( *hHeadTrackData )->sr_pose_pred_axis = DEFAULT_AXIS; -#endif set_zero( ( *hHeadTrackData )->chEneIIR[0], MASA_FREQUENCY_BANDS ); set_zero( ( *hHeadTrackData )->chEneIIR[1], MASA_FREQUENCY_BANDS ); @@ -157,7 +147,6 @@ void QuatToRotMat( float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( quat.w == -3.0 ) { IVAS_QUATERNION quat_local; @@ -166,7 +155,6 @@ void QuatToRotMat( } else { -#endif Rmat[0][0] = quat.w * quat.w + quat.x * quat.x - quat.y * quat.y - quat.z * quat.z; Rmat[0][1] = 2.0f * ( quat.x * quat.y - quat.w * quat.z ); Rmat[0][2] = 2.0f * ( quat.x * quat.z + quat.w * quat.y ); @@ -178,108 +166,12 @@ void QuatToRotMat( Rmat[2][0] = 2.0f * ( quat.x * quat.z - quat.w * quat.y ); Rmat[2][1] = 2.0f * ( quat.y * quat.z + quat.w * quat.x ); Rmat[2][2] = quat.w * quat.w - quat.x * quat.x - quat.y * quat.y + quat.z * quat.z; -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif - - return; -} - - -/*------------------------------------------------------------------------- - * Euler2Quat() - * - * Calculate corresponding Quaternion from Euler angles in radians - *------------------------------------------------------------------------*/ - -void Euler2Quat( - const float yaw, /* i : yaw (x) */ - const float pitch, /* i : pitch (y) */ - const float roll, /* i : roll (z) */ - IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ -) -{ - float cr = cosf( roll * 0.5f ); - float sr = sinf( roll * 0.5f ); - float cp = cosf( pitch * 0.5f ); - float sp = sinf( pitch * 0.5f ); - float cy = cosf( yaw * 0.5f ); - float sy = sinf( yaw * 0.5f ); - quat->w = cr * cp * cy + sr * sp * sy; - quat->x = sr * cp * cy - cr * sp * sy; - quat->y = sr * cp * sy + cr * sp * cy; - quat->z = cr * cp * sy - sr * sp * cy; return; } -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*------------------------------------------------------------------------- - * Quat2EulerDegree() - * - * Quaternion handling: calculate corresponding Euler angles in degrees - *------------------------------------------------------------------------*/ - -void Quat2EulerDegree( - const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ - float *yaw, /* o : yaw */ - float *pitch, /* o : pitch */ - float *roll /* o : roll */ -) -{ - if ( quat.w != -3.0 ) - { - float p; - *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) ); - p = 2 * ( quat.w * quat.y - quat.z * quat.x ); - p = max( -1.0f, min( 1.0f, p ) ); - *pitch = asinf( p ); - *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) ); - *yaw *= _180_OVER_PI; - *pitch *= _180_OVER_PI; - *roll *= _180_OVER_PI; - } - else - { - /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention - * - * yaw: rotate scene counter-clockwise in the horizontal plane - * pitch: rotate scene in the median plane, increase elevation with positive values - * roll: rotate scene from the right ear to the top - */ - *yaw = quat.z; - *pitch = quat.y; - *roll = quat.x; - } - - return; -} -#endif - - -/*------------------------------------------------------------------------- - * deg2rad() - * - * Converts degrees to normalized radians - *------------------------------------------------------------------------*/ - -float deg2rad( - float degrees ) -{ - while ( degrees >= 180.0f ) - { - degrees = degrees - 360.0f; - } - while ( degrees <= -180.0f ) - { - degrees = degrees + 360.0f; - } - - return PI_OVER_180 * degrees; -} - - /*------------------------------------------------------------------------- * rad2deg() * @@ -388,11 +280,7 @@ void rotateFrame_shd( } /* calculate ambisonics rotation matrices for the previous and current frames */ -#ifdef SPLIT_REND_WITH_HEAD_ROT SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev[0], shd_rot_max_order ); -#else - SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev, shd_rot_max_order ); -#endif SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], shd_rot_max_order ); @@ -449,11 +337,7 @@ void rotateFrame_shd( { mvr2r( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], -#ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->Rmat_prev[0][i], -#else - hCombinedOrientationData->Rmat_prev[i], -#endif 3 ); } @@ -519,11 +403,7 @@ void rotateFrame_sd( ch_in_woLFE = ( ch_in >= index_lfe ) ? ch_in - 1 : ch_in; /* gains for previous subframe rotation */ -#ifdef SPLIT_REND_WITH_HEAD_ROT rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev[0], hTransSetup.is_planar_setup ); -#else - rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev, hTransSetup.is_planar_setup ); -#endif if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { @@ -584,11 +464,7 @@ void rotateFrame_sd( { mvr2r( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], -#ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->Rmat_prev[0][i], -#else - hCombinedOrientationData->Rmat_prev[i], -#endif 3 ); } @@ -880,9 +756,7 @@ ivas_error ivas_combined_orientation_open( int16_t j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif identity.w = 1.0f; identity.x = identity.y = identity.z = 0.0f; @@ -920,7 +794,6 @@ ivas_error ivas_combined_orientation_open( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { for ( j = 0; j < 3; j++ ) @@ -931,13 +804,6 @@ ivas_error ivas_combined_orientation_open( } ( *hCombinedOrientationData )->sr_pose_pred_axis = DEFAULT_AXIS; ( *hCombinedOrientationData )->sr_low_res_flag = 0; -#else - for ( j = 0; j < 3; j++ ) - { - set_zero( ( *hCombinedOrientationData )->Rmat_prev[j], 3 ); - ( *hCombinedOrientationData )->Rmat_prev[j][j] = 1.0f; - } -#endif ( *hCombinedOrientationData )->Quaternion_prev_extOrientation = identity; ( *hCombinedOrientationData )->Quaternion_frozen_ext = identity; @@ -994,9 +860,7 @@ ivas_error combine_external_and_head_orientations_dec( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; -#endif + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; IVAS_QUATERNION *pHeadRotQuaternion = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -1004,22 +868,14 @@ ivas_error combine_external_and_head_orientations_dec( { pHeadRotQuaternion = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; -#ifdef SPLIT_REND_WITH_HEAD_ROT sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; -#endif } -#ifdef SPLIT_REND_WITH_HEAD_ROT else { sr_pose_pred_axis = DEFAULT_AXIS; } -#endif - return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, -#ifdef SPLIT_REND_WITH_HEAD_ROT - sr_pose_pred_axis, -#endif - hExtOrientationData, hCombinedOrientationData ); + return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, sr_pose_pred_axis, hExtOrientationData, hCombinedOrientationData ); } @@ -1035,16 +891,12 @@ ivas_error combine_external_and_head_orientations_rend( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; -#endif + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; int16_t i; -#ifdef SPLIT_REND_WITH_HEAD_ROT sr_pose_pred_axis = DEFAULT_AXIS; -#endif if ( hHeadTrackData != NULL ) { if ( hHeadTrackData->headRotEnabled ) @@ -1052,9 +904,7 @@ ivas_error combine_external_and_head_orientations_rend( headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; } -#ifdef SPLIT_REND_WITH_HEAD_ROT sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; -#endif } else if ( hExtOrientationData != NULL ) { @@ -1068,11 +918,7 @@ ivas_error combine_external_and_head_orientations_rend( } } - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, -#ifdef SPLIT_REND_WITH_HEAD_ROT - sr_pose_pred_axis, -#endif - hExtOrientationData, hCombinedOrientationData ); + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, sr_pose_pred_axis, hExtOrientationData, hCombinedOrientationData ); } @@ -1084,11 +930,9 @@ ivas_error combine_external_and_head_orientations_rend( *------------------------------------------------------------------------*/ ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ - IVAS_VECTOR3 *listenerPos, /* i : listener position */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ -#endif + IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) @@ -1334,9 +1178,7 @@ ivas_error combine_external_and_head_orientations( dbgwrite( &( hCombinedOrientationData->Quaternions[i].z ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_z.dat" ); } #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; -#endif hCombinedOrientationData->subframe_idx = 0; hCombinedOrientationData->cur_subframe_samples_rendered = 0; hCombinedOrientationData->subframe_idx_start = 0; @@ -1557,11 +1399,7 @@ static float SHrot_w( if ( m == 0 ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT assert( 0 && "ERROR should not be called\n" ); -#else - printf( "ERROR should not be called\n" ); -#endif return 0.0f; } else @@ -1708,11 +1546,7 @@ void ivas_combined_orientation_update_index( { if ( hCombinedOrientationData != NULL ) { - if ( hCombinedOrientationData->num_subframes == 1 -#ifdef SPLIT_REND_WITH_HEAD_ROT - || hCombinedOrientationData->sr_low_res_flag -#endif - ) + if ( hCombinedOrientationData->num_subframes == 1 || hCombinedOrientationData->sr_low_res_flag ) { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; @@ -1763,11 +1597,7 @@ void ivas_combined_orientation_update_start_index( { if ( hCombinedOrientationData != NULL ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( hCombinedOrientationData->num_subframes == 1 || hCombinedOrientationData->sr_low_res_flag ) -#else - if ( hCombinedOrientationData->num_subframes == 1 ) -#endif { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index e984eed05443521beb01938b83c0f48afe918d02..8c373e1fed49f995035b5a5c43fe11a92c49c453 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -33,6 +33,7 @@ #include "options.h" #include #include +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 672f2642119b7153f3d589794f208e8714600508..8837531280f4c48cad422f0310ee6896df5963a1 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -39,12 +39,7 @@ #include "ivas_stat_com.h" // note: needed for DIRAC_DEC_BIN_HANDLE until #156 is solved #include "stat_com.h" /* Note: Currently needed for CLDFB. */ #include "common_api_types.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "stat_com.h" -#include "ivas_lcld_prot.h" -#include "ivas_lc3plus_enc.h" -#include "ivas_lc3plus_dec.h" -#endif +#include "isar_stat.h" /*----------------------------------------------------------------------------------* @@ -485,7 +480,6 @@ typedef struct ivas_binaural_reverb_struct uint32_t binRend_RandNext; int16_t highestBinauralCoherenceBin; - float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; } REVERB_STRUCT, *REVERB_STRUCT_HANDLE; @@ -563,13 +557,8 @@ typedef struct ivas_binaural_rendering_conv_module_struct float ***filterTapsRightReal; float ***filterTapsRightImag; -#ifdef SPLIT_REND_WITH_HEAD_ROT float ****filterStatesLeftReal; float ****filterStatesLeftImag; -#else - float ***filterStatesLeftReal; - float ***filterStatesLeftImag; -#endif int16_t numTapsArray[BINAURAL_CONVBANDS]; int16_t numTaps; @@ -587,7 +576,7 @@ typedef struct EFAP_VERTEX float ele; /* elevation of the loudspeaker */ float pos[3]; /* [x y z] cartesian coordinate vector */ int16_t idx; /* integer, that corresponds to the first index for the LS in the 1D output */ - int16_t isNaN; /* used to indicate if the vertex is a virtual speaker */ + bool isNaN; /* used to indicate if the vertex is a virtual speaker */ EFAP_VTX_DMX_TYPE dmxType; /* virtual speaker downmix type */ } EFAP_VERTEX; @@ -603,7 +592,7 @@ typedef struct EFAP_VERTEX_DATA typedef struct EFAP_POLYSET { int16_t chan[EFAP_MAX_CHAN_NUM]; /* An array indicating the loudspeaker index of the polygon vertices */ - int16_t isNaN[EFAP_MAX_CHAN_NUM]; /* Indicates if one of the vertices isNaN */ + bool isNaN[EFAP_MAX_CHAN_NUM]; /* Indicates if one of the vertices isNaN */ int16_t numChan; /* An integer between 0 and EFAP_MAX_CHAN_NUM corresponding to the number of vertices of the polygon */ float polyAzi[EFAP_MAX_CHAN_NUM]; /* An array (same length as "chan"), with the azimuth of the channels */ float polyEle[EFAP_MAX_CHAN_NUM]; /* An array (same length as "chan"), with the elevation of the channels */ @@ -618,10 +607,10 @@ typedef struct EFAP_LS_TRIANGLE typedef struct EFAP_POLYSET_DATA { - EFAP_POLYSET polysetArray[EFAP_MAX_POLY_SET]; /* Array of polygons */ - int16_t numPoly; /* Number of polygons */ - EFAP_LS_TRIANGLE triArray[EFAP_MAX_POLY_SET]; /* Array of triangles */ - int16_t numTri; /* Number of triangles */ + EFAP_POLYSET *polysetArray; /* Array of polygons */ + int16_t numPoly; /* Number of polygons */ + EFAP_LS_TRIANGLE *triArray; /* Array of triangles */ + int16_t numTri; /* Number of triangles */ } EFAP_POLYSET_DATA; @@ -640,7 +629,7 @@ typedef struct EFAP } EFAP, *EFAP_HANDLE; /*----------------------------------------------------------------------------------* - * Orientation tracking structure + * Head rotation data structure *----------------------------------------------------------------------------------*/ typedef struct ivas_orient_trk_state_t @@ -657,19 +646,13 @@ typedef struct ivas_orient_trk_state_t } ivas_orient_trk_state_t; -/*----------------------------------------------------------------------------------* - * Head rotation data structure - *----------------------------------------------------------------------------------*/ - typedef struct { int8_t headRotEnabled; - IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES]; - IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; - float crossfade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; -#endif + IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; @@ -691,31 +674,10 @@ typedef struct ivas_binaural_head_track_struct int16_t shd_rot_max_order; ivas_orient_trk_state_t *OrientationTracker; -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; -#endif + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; -/*----------------------------------------------------------------------------------* - * External orientation data structure - *----------------------------------------------------------------------------------*/ - -typedef struct ivas_external_orientation_struct -{ - int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ - int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ - int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ - int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ - IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ - int16_t num_subframes; - -} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; - -/*----------------------------------------------------------------------------------* - * Combined orientation data structure for the external orienations and head orientation - *----------------------------------------------------------------------------------*/ - typedef struct ivas_combined_orientation_struct { int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -731,19 +693,13 @@ typedef struct ivas_combined_orientation_struct IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3]; -#ifdef SPLIT_REND_WITH_HEAD_ROT float Rmat_prev[MAX_HEAD_ROT_POSES][3][3]; -#else - float Rmat_prev[3][3]; -#endif float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ float procChEneIIR[2][MASA_FREQUENCY_BANDS]; int16_t shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; int16_t sr_low_res_flag; -#endif IVAS_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; int8_t isExtOrientationFrozen; @@ -756,6 +712,21 @@ typedef struct ivas_combined_orientation_struct int16_t cur_subframe_samples_rendered_start; } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; +/*----------------------------------------------------------------------------------* + * External orientation data structure + *----------------------------------------------------------------------------------*/ + +typedef struct ivas_external_orientation_struct +{ + int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ + int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ + int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ + int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ + int16_t num_subframes; + +} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; + /*----------------------------------------------------------------------------------* * Reverberator structure @@ -839,7 +810,6 @@ typedef struct ivas_reverb_state_t uint16_t fft_subblock_size; /* fft block processing size */ uint16_t num_fft_subblocks; /* number of fft subblocks */ uint16_t full_block_size; /* full block processing size */ - } REVERB_DATA, *REVERB_HANDLE; @@ -936,19 +906,16 @@ typedef struct er_struct_t typedef struct { - int16_t modelROM; /* Flag that indicates that the model resides in ROM (controls init/dealloc). */ - int16_t UseItdModel; /* Controls whether ITD model is used. */ - int16_t SplineDegree; /* Degree of the spline functions */ - int16_t K; /* Length of filter */ - int16_t elevDim2; + int16_t modelROM; /* Flag that indicates that the model resides in ROM (controls init/dealloc). */ + int16_t UseItdModel; /* Controls whether ITD model is used. */ + int16_t K; /* Length of filter */ int16_t elevDim3; int16_t AlphaN; /* Number of rows in Alpha matrices */ int16_t num_unique_azim_splines; int16_t elevSegSamples; - int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; - int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; - const int16_t *azimDim2; + const int16_t *elevBsLen; + const int16_t *elevBsStart; const int16_t *azimDim3; const int16_t *azim_start_idx; const int16_t *azimSegSamples; @@ -975,7 +942,8 @@ typedef struct float *ER_dyn; float *elevBsShape_dyn; float *elevKSeq_dyn; - int16_t *azimDim2_dyn; + int16_t *elevBsLen_dyn; + int16_t *elevBsStart_dyn; int16_t *azimDim3_dyn; int16_t *azim_start_idx_dyn; int16_t *azimSegSamples_dyn; @@ -987,23 +955,19 @@ typedef struct typedef struct { - int16_t N; /* Polynomial degree */ - - int16_t elevDim2; int16_t elevDim3; const float *elevKSeq; /* Array, length elevDim3-2 */ - int16_t azimDim2; int16_t azimDim3; const float *azimKSeq; /* Array, length azimDim3-2 */ const float *W; /* Array, size (elevDim3*azimDim3) x K */ - int16_t azimBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; - int16_t azimBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + const int16_t *azimBsLen; + const int16_t *azimBsStart; const float *azimBsShape; int16_t azimSegSamples; - int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; - int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; + const int16_t *elevBsLen; + const int16_t *elevBsStart; const float *elevBsShape; int16_t elevSegSamples; float resamp_factor; @@ -1014,6 +978,10 @@ typedef struct float *W_dyn; float *azimBsShape_dyn; float *elevBsShape_dyn; + int16_t *azimBsLen_dyn; + int16_t *azimBsStart_dyn; + int16_t *elevBsLen_dyn; + int16_t *elevBsStart_dyn; } ModelParamsITD_t; @@ -1235,17 +1203,12 @@ typedef struct ivas_crend_state_t typedef struct ivas_binaural_crend_wrapper_struct { int32_t binaural_latency_ns; -#ifdef SPLIT_REND_WITH_HEAD_ROT CREND_HANDLE hCrend[MAX_HEAD_ROT_POSES]; -#else - CREND_HANDLE hCrend; -#endif HRTFS_HANDLE hHrtfCrend; } CREND_WRAPPER, *CREND_WRAPPER_HANDLE; -#ifdef SPLIT_REND_WITH_HEAD_ROT /* Fastconv binaural data structure */ typedef struct ivas_binaural_rendering_struct { @@ -1271,7 +1234,6 @@ typedef struct ivas_binaural_rendering_struct int16_t numPoses; } BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; -#endif /*------------------------------------------------------------------------------------------* * HRTF structures - hrtfs from binary files @@ -1336,195 +1298,6 @@ typedef struct ivas_hrtfs_statistics_struct int16_t fromROM; /* Flag that indicates that the pointers point to tables in ROM (controls init/dealloc).*/ } HRTFS_STATISTICS, *HRTFS_STATISTICS_HANDLE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Binaural split rendering structures - *----------------------------------------------------------------------------------*/ - -/* binaural split rendering head rotation data structure */ -typedef struct ivas_binaural_head_rot_split_rendering_md_struct -{ - float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float gd; - float gd2; - int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - int16_t gd_idx; - int16_t gd2_idx; - -} BIN_HR_SPLIT_REND_MD, *BIN_HR_SPLIT_REND_MD_HANDLE; - -typedef struct ivas_split_rend_huffman_cfg_t -{ - const int32_t *codebook; - int16_t min_len; - int16_t max_len; - int16_t sym_len; - -} ivas_split_rend_huffman_cfg_t; - -typedef struct ivas_binaural_head_rot_split_rendering_huff_struct -{ - ivas_split_rend_huffman_cfg_t pred[2]; - int16_t pred_idx_trav[2][IVAS_SPLIT_REND_PRED_63QUANT_PNTS]; - int16_t pred_base2_code_len[2]; - ivas_split_rend_huffman_cfg_t pred_roll; - int16_t pred_roll_idx_trav[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; - int16_t pred_roll_base2_code_len; - ivas_split_rend_huffman_cfg_t gd; - int16_t gd_base2_code_len; - int16_t gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; - ivas_split_rend_huffman_cfg_t p_gd; - int16_t p_gd_base2_code_len; - int16_t p_gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; - ivas_split_rend_huffman_cfg_t p_gd_diff; - int16_t p_gd_diff_base2_code_len; - int16_t p_gd_diff_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; - -} BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; - - -typedef struct ivas_binaural_head_rot_split_post_rendering_struct -{ - BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; - IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t low_Res; - - float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; - BIN_HR_SPLIT_REND_HUFF huff_cfg; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; -#else - float mixer_mat_re[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float mixer_mat_im[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float gd_mem[1][MAX_SPLIT_REND_MD_BANDS]; -#endif - int16_t cf_flag; - HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; - HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; -#endif - -} BIN_HR_SPLIT_POST_REND, *BIN_HR_SPLIT_POST_REND_HANDLE; - -typedef struct ivas_binaural_head_rot_split_pre_rendering_struct -{ - BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; - float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; - BIN_HR_SPLIT_REND_HUFF huff_cfg; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; -#endif - -#ifdef SPLIT_POSE_CORRECTION_DEBUG - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; -#endif - -} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; - -typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct -{ - void *pLcld_enc; - int16_t iChannels; - LCLDEncoder *psLCLDEncoder; - float ***pppfLCLDReal; - float ***pppfLCLDImag; -#ifdef CLDFB_DEBUG - FILE *cldfbIn; - int16_t numFrame; -#endif - int16_t iNumIterations; - int16_t iNumBlocks; - -} BIN_HR_SPLIT_LCLD_ENC, *BIN_HR_SPLIT_LCLD_ENC_HANDLE; - -typedef struct -{ - float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; -#if CLDFB_PLC_XF > 0 - float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; -#endif - -} CLDFB_PLC, *CLDFB_PLC_HANDLE; - -typedef struct -{ - CLDFB_PLC CldfbPLC_state; - int16_t prev_bfi; - int16_t bf_count; - -} SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE; - -typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct -{ - void *pLcld_dec; - int32_t iChannels; - LCLDDecoder *psLCLDDecoder; - float ***pppfDecLCLDReal; - float ***pppfDecLCLDImag; -#ifdef CLDFB_DEBUG - FILE *cldfbOut; - int16_t numFrame; -#endif - SPLIT_REND_PLC_HANDLE hSplitRendPLC; - int16_t iNumBlocks; - int16_t iNumIterations; - -} BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; - -typedef struct -{ -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; -#else - HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; -#endif - HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; - -} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; - -typedef struct -{ - int16_t num_poses; - float relative_head_poses[MAX_HEAD_ROT_POSES][3]; - int16_t dof; - int16_t hq_mode; - IVAS_SPLIT_REND_ROT_AXIS rot_axis; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; - -} MULTI_BIN_REND_POSE_DATA; - -typedef struct -{ - MULTI_BIN_REND_POSE_DATA multiBinPoseData; - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; - BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; - CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; - IVAS_LC3PLUS_ENC_HANDLE hLc3plusEnc; - BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; - float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ - int32_t lc3plusDelaySamples; - -} SPLIT_REND_WRAPPER; - -typedef struct -{ - MULTI_BIN_REND_POSE_DATA multiBinPoseData; - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; - int16_t first_good_frame_received; - IVAS_LC3PLUS_DEC_HANDLE hLc3plusDec; - -} SPLIT_POST_REND_WRAPPER; -#endif - /*----------------------------------------------------------------------------------* * Limiter structure @@ -1599,7 +1372,15 @@ typedef struct ivas_LS_setup_custom } LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; -#ifdef SPLIT_REND_WITH_HEAD_ROT +/* Channel types in a channel-based config */ +typedef enum +{ + CHANNEL_TYPE_UNUSED = 0, + CHANNEL_TYPE_SPEAKER, + CHANNEL_TYPE_LFE + +} ChannelType; + /*----------------------------------------------------------------------------------* * CLDFB renderer wrapper @@ -1613,16 +1394,6 @@ typedef struct } CLDFB_REND_WRAPPER; -#endif - -/* Channel types in a channel-based config */ -typedef enum -{ - CHANNEL_TYPE_UNUSED = 0, - CHANNEL_TYPE_SPEAKER, - CHANNEL_TYPE_LFE - -} ChannelType; /*----------------------------------------------------------------------------------* * MASA external renderer structure @@ -1635,11 +1406,7 @@ typedef struct ivas_masa_external_rendering_struct RENDERER_TYPE renderer_type; DIRAC_REND_HANDLE hDirACRend; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; -#ifdef SPLIT_REND_WITH_HEAD_ROT DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; -#else - DIRAC_DEC_BIN_HANDLE hDiracDecBin; -#endif REVERB_STRUCT_HANDLE hReverb; HRTFS_PARAMBIN_HANDLE *hHrtfParambin; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a6ddac23a9ccd562ac7b1b3671447f9a3479ff86..6e3257b6c887b548f24db5430248eb156f52ba57 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -35,6 +35,8 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#include "isar_prot.h" +#include "lib_isar_pre_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" @@ -48,30 +50,10 @@ * Local constants *-------------------------------------------------------------------*/ -/* Maximum buffer length (per channel) in samples. - * Keep this separate from L_FRAME48k in case we want to support different size later */ -#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) -#endif - /* Maximum buffer length (total) in samples. */ -/* Maximum buffer length (total) in samples. */ -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) -#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) -#else -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#endif - +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) #define MAX_BIN_DELAY_SAMPLES 150 /* Maximum supported rendering latency for binaural IRs */ -/* Frame size required when rendering to binaural */ -#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 - - /*-------------------------------------------------------------------* * Local types *-------------------------------------------------------------------*/ @@ -103,11 +85,9 @@ typedef struct const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; const EFAP_WRAPPER *pEfapOutWrapper; const IVAS_REND_HeadRotData *pHeadRotData; -#ifdef SPLIT_REND_WITH_HEAD_ROT const RENDER_CONFIG_HANDLE *hhRendererConfig; const int16_t *pSplitRendBFI; const SPLIT_REND_WRAPPER *pSplitRendWrapper; -#endif const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData; } rendering_context; @@ -133,9 +113,7 @@ typedef struct rotation_matrix rot_mat_prev; pan_vector prev_pan_gains; int8_t firstFrameRendered; -#ifdef SPLIT_REND_WITH_HEAD_ROT TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ -#endif float *bufferData; int16_t nonDiegeticPan; float nonDiegeticPanGain; @@ -166,15 +144,9 @@ typedef struct EFAP_WRAPPER efapInWrapper; TDREND_WRAPPER tdRendWrapper; CREND_WRAPPER_HANDLE crendWrapper; -#ifdef SPLIT_REND_WITH_HEAD_ROT TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ -#endif REVERB_HANDLE hReverb; -#ifdef SPLIT_REND_WITH_HEAD_ROT rotation_gains rot_gains_prev[MAX_HEAD_ROT_POSES]; -#else - rotation_gains rot_gains_prev; -#endif int16_t nonDiegeticPan; float nonDiegeticPanGain; lfe_routing lfeRouting; @@ -188,31 +160,13 @@ typedef struct { input_base base; pan_matrix hoaDecMtx; -#ifdef SPLIT_REND_WITH_HEAD_ROT CLDFB_REND_WRAPPER cldfbRendWrapper; -#endif CREND_WRAPPER_HANDLE crendWrapper; -#ifdef SPLIT_REND_WITH_HEAD_ROT rotation_gains rot_gains_prev[MAX_HEAD_ROT_POSES]; -#else - rotation_gains rot_gains_prev; -#endif float *bufferData; DIRAC_ANA_HANDLE hDirAC; } input_sba; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef struct -{ - input_base base; - SPLIT_POST_REND_WRAPPER splitPostRendWrapper; - float *bufferData; - int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ - IVAS_REND_BitstreamBuffer *hBits; -} input_split_post_rend; -#endif - - typedef struct { input_base base; @@ -245,23 +199,16 @@ struct IVAS_REND input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; -#endif AUDIO_CONFIG inputConfig; AUDIO_CONFIG outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; -#ifdef SPLIT_REND_WITH_HEAD_ROT SPLIT_REND_WRAPPER splitRendWrapper; IVAS_REND_AudioBuffer splitRendEncBuffer; -#endif IVAS_REND_HeadRotData headRotData; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t splitRendBFI; -#endif EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; @@ -282,6 +229,10 @@ static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); +static void renderSbaToMultiBinauralCldfb( input_sba *sbaInput, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t low_res_pre_rend_rot, const int16_t num_subframes ); + +static ivas_error renderSbaToMultiBinaural( input_sba *sbaInput, const AUDIO_CONFIG outConfig, float out[][L_FRAME48k] ); + /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -353,10 +304,9 @@ static float *getSmplPtr( return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } -#ifdef SPLIT_REND_WITH_HEAD_ROT static void convertBitsBufferToInternalBitsBuff( const IVAS_REND_BitstreamBuffer outBits, - IVAS_SPLIT_REND_BITS_HANDLE hBits ) + ISAR_SPLIT_REND_BITS_HANDLE hBits ) { hBits->bits_buf = outBits.bits; hBits->bits_read = outBits.config.bitsRead; @@ -371,7 +321,7 @@ static void convertBitsBufferToInternalBitsBuff( static void convertInternalBitsBuffToBitsBuffer( IVAS_REND_BitstreamBuffer *hOutBits, - const IVAS_SPLIT_REND_BITS_DATA bits ) + const ISAR_SPLIT_REND_BITS_DATA bits ) { hOutBits->bits = bits.bits_buf; hOutBits->config.bitsRead = bits.bits_read; @@ -447,7 +397,6 @@ static void accumulateCLDFBArrayToBuffer( return; } -#endif static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, @@ -457,9 +406,7 @@ static void copyBufferTo2dArray( uint32_t chnlIdx; const float *readPtr; -#ifdef SPLIT_REND_WITH_HEAD_ROT assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); -#endif readPtr = buffer.data; for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) @@ -475,10 +422,7 @@ static void copyBufferTo2dArray( static void accumulate2dArrayToBuffer( float array[][L_FRAME48k], -#ifdef SPLIT_REND_WITH_HEAD_ROT - const -#endif - IVAS_REND_AudioBuffer *buffer ) + const IVAS_REND_AudioBuffer *buffer ) { int16_t smplIdx, chnlIdx; float *writePtr; @@ -571,10 +515,8 @@ static ivas_error validateOutputAudioConfig( case IVAS_AUDIO_CONFIG_HOA2: case IVAS_AUDIO_CONFIG_HOA3: case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: -#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA1: @@ -654,15 +596,12 @@ static ivas_error validateOutputSampleRate( /* If no binaural rendering, any sampling rate is supported */ return IVAS_ERR_OK; } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); } else { -#endif - /* Otherwise rendering to binaural, support the same set as IVAS decoder */ switch ( sampleRate ) { @@ -674,9 +613,7 @@ static ivas_error validateOutputSampleRate( } return IVAS_ERR_INVALID_SAMPLING_RATE; -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } @@ -699,10 +636,8 @@ ivas_error getAudioConfigNumChannels( break; case IVAS_AUDIO_CONFIG_STEREO: case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: -#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA2: @@ -1156,9 +1091,7 @@ static ivas_error initHeadRotation( hIvasRend->headRotData.headPositions[i] = quaternionInit(); } -#ifdef SPLIT_REND_WITH_HEAD_ROT hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; -#endif if ( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -1283,11 +1216,9 @@ static rendering_context getRendCtx( ctx.pCustomLsOut = &hIvasRend->customLsOut; ctx.pEfapOutWrapper = &hIvasRend->efapOutWrapper; ctx.pHeadRotData = &hIvasRend->headRotData; -#ifdef SPLIT_REND_WITH_HEAD_ROT ctx.hhRendererConfig = &hIvasRend->hRendererConfig; ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; ctx.pSplitRendWrapper = &hIvasRend->splitRendWrapper; -#endif ctx.pCombinedOrientationData = &hIvasRend->hCombinedOrientationData; return ctx; @@ -1333,11 +1264,7 @@ static ivas_error initIsmMasaRendering( ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputIsm->crendWrapper, inputIsm->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &inputIsm->crendWrapper ); -#endif ivas_reverb_close( &inputIsm->hReverb ); @@ -1361,9 +1288,7 @@ static ivas_error setRendInputActiveIsm( rendering_context rendCtx; AUDIO_CONFIG outConfig; input_ism *inputIsm; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t i; -#endif inputIsm = (input_ism *) input; rendCtx = inputIsm->base.ctx; @@ -1390,31 +1315,19 @@ static ivas_error setRendInputActiveIsm( initRotMatrix( inputIsm->rot_mat_prev ); set_zero( inputIsm->prev_pan_gains, MAX_OUTPUT_CHANNELS ); -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) { inputIsm->splitTdRendWrappers[i] = defaultTdRendWrapper(); inputIsm->splitTdRendWrappers[i].hHrtfTD = &hrtfs->hHrtfTD; } -#endif inputIsm->hOMasa = NULL; error = IVAS_ERR_OK; inputIsm->tdRendWrapper.hHrtfTD = &hrtfs->hHrtfTD; -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) -#endif { -#ifndef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } -#else if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; @@ -1431,7 +1344,6 @@ static ivas_error setRendInputActiveIsm( /* Assert same delay as main TD renderer */ assert( inputIsm->splitTdRendWrappers[i].binaural_latency_ns == inputIsm->tdRendWrapper.binaural_latency_ns ); } -#endif } else if ( outConfig == IVAS_AUDIO_CONFIG_MASA1 || outConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -1442,20 +1354,6 @@ static ivas_error setRendInputActiveIsm( } else { -#ifndef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), hrtfs->hHrtfStatistics, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#else if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; @@ -1475,7 +1373,6 @@ static ivas_error setRendInputActiveIsm( return error; } } -#endif } return IVAS_ERR_OK; @@ -1486,9 +1383,7 @@ static void clearInputIsm( input_ism *inputIsm ) { rendering_context rendCtx; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t i; -#endif rendCtx = inputIsm->base.ctx; @@ -1496,11 +1391,7 @@ static void clearInputIsm( initRendInputBase( &inputIsm->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); /* Free input's internal handles */ -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputIsm->crendWrapper, inputIsm->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &inputIsm->crendWrapper ); -#endif ivas_reverb_close( &inputIsm->hReverb ); @@ -1509,12 +1400,10 @@ static void clearInputIsm( ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) { ivas_td_binaural_close( &inputIsm->splitTdRendWrappers[i].hBinRendererTd ); } -#endif ivas_omasa_ana_close( &( inputIsm->hOMasa ) ); @@ -2108,10 +1997,8 @@ static ivas_error updateMcPanGains( switch ( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: -#endif break; /* Do nothing */ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -2161,9 +2048,7 @@ static ivas_error initMcBinauralRendering( uint8_t reconfigureFlag ) { ivas_error error; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t i; -#endif int32_t binauralDelayNs; int32_t outSampleRate; int8_t useTDRend; @@ -2190,7 +2075,6 @@ static ivas_error initMcBinauralRendering( ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( !reconfigureFlag || !useTDRend ) { for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) @@ -2201,16 +2085,11 @@ static ivas_error initMcBinauralRendering( } } } -#endif /* if we need to use TD renderer and CREND was open, close it */ if ( useTDRend ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &inputMc->crendWrapper ); -#endif } if ( !reconfigureFlag || ( !useTDRend && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && inputMc->hReverb != NULL ) ) @@ -2235,7 +2114,6 @@ static ivas_error initMcBinauralRendering( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { /* Open TD renderer wrappers */ @@ -2251,7 +2129,6 @@ static ivas_error initMcBinauralRendering( } } -#endif if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && inputMc->hReverb == NULL ) { if ( ( error = ivas_reverb_open( &( inputMc->hReverb ), hHrtfStatistics, hRendCfg, outSampleRate ) ) != IVAS_ERR_OK ) @@ -2263,12 +2140,8 @@ static ivas_error initMcBinauralRendering( else if ( !useTDRend && inputMc->crendWrapper == NULL ) { /* open CREND */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, outSampleRate, ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) ? inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, outSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2308,11 +2181,7 @@ static ivas_error initMcMasaRendering( ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &inputMc->crendWrapper ); -#endif ivas_reverb_close( &inputMc->hReverb ); @@ -2396,16 +2265,12 @@ static ivas_error setRendInputActiveMc( RENDER_CONFIG_DATA *hRendCfg, hrtf_handles *hrtfs ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t i; -#endif ivas_error error; rendering_context rendCtx; AUDIO_CONFIG outConfig; input_mc *inputMc; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif inputMc = (input_mc *) input; rendCtx = inputMc->base.ctx; @@ -2440,19 +2305,14 @@ static ivas_error setRendInputActiveMc( inputMc->hReverb = NULL; inputMc->hMcMasa = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { initRotGains( inputMc->rot_gains_prev[pos_idx] ); } -#else - initRotGains( inputMc->rot_gains_prev ); -#endif inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); set_zero( inputMc->lfeDelayBuffer, MAX_BIN_DELAY_SAMPLES ); inputMc->binauralDelaySmp = 0; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) { inputMc->splitTdRendWrappers[i] = defaultTdRendWrapper(); @@ -2464,9 +2324,6 @@ static ivas_error setRendInputActiveMc( } if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) -#else - if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif { if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, FALSE ) ) != IVAS_ERR_OK ) { @@ -2494,9 +2351,7 @@ static ivas_error setRendInputActiveMc( static void clearInputMc( input_mc *inputMc ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t i; -#endif rendering_context rendCtx; rendCtx = inputMc->base.ctx; @@ -2511,11 +2366,7 @@ static void clearInputMc( efap_free_data( &inputMc->efapInWrapper.hEfap ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &inputMc->crendWrapper ); -#endif ivas_reverb_close( &inputMc->hReverb ); @@ -2524,7 +2375,6 @@ static void clearInputMc( ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) { if ( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) @@ -2532,7 +2382,6 @@ static void clearInputMc( ivas_td_binaural_close( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); } } -#endif ivas_mcmasa_ana_close( &( inputMc->hMcMasa ) ); @@ -2630,35 +2479,6 @@ static ivas_error initSbaPanGainsForSbaOut( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error updateSplitPostRendPanGains( - input_split_post_rend *inputSplitPostRend, - const AUDIO_CONFIG outConfig, - RENDER_CONFIG_DATA *hRendCfg ) -{ - ivas_error error; - rendering_context rendCtx; - int16_t numOutChannels; - - if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) - { - - return error; - } - - rendCtx = inputSplitPostRend->base.ctx; - ivas_renderSplitGetMultiBinPoseData( &hRendCfg->split_rend_config, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); - - if ( ( error = ivas_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } - - return IVAS_ERR_OK; -} -#endif - - static ivas_error updateSbaPanGains( input_sba *inputSba, const AUDIO_CONFIG outConfig, @@ -2687,11 +2507,10 @@ static ivas_error updateSbaPanGains( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: { - if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { assert( inConfig == IVAS_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" ); @@ -2710,10 +2529,8 @@ static ivas_error updateSbaPanGains( } break; } -#endif case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { @@ -2721,13 +2538,8 @@ static ivas_error updateSbaPanGains( } } else -#endif { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2740,11 +2552,7 @@ static ivas_error updateSbaPanGains( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2770,63 +2578,13 @@ static ivas_error updateSbaPanGains( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error setRendInputActiveSplitPostRend( - void *input, - const AUDIO_CONFIG inConfig, - const IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRendCfg, -#if defined _MSC_VER && !defined __clang__ -#ifdef _MSC_VER -#pragma warning( disable : 4100 ) -#endif - hrtf_handles *hrtfs -#ifdef _MSC_VER -#pragma warning( default : 4100 ) -#endif -#else - hrtf_handles *hrtfs __attribute__( ( unused ) ) /* avoid unused parameter warning when compiling with clang */ -#endif -) -{ - ivas_error error; - rendering_context rendCtx; - AUDIO_CONFIG outConfig; - input_split_post_rend *inputSplitPostRend; - - inputSplitPostRend = (input_split_post_rend *) input; - rendCtx = inputSplitPostRend->base.ctx; - outConfig = *rendCtx.pOutConfig; - - if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) - { - return error; - } - - initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); - inputSplitPostRend->numCachedSamples = 0; - - if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) - { - return error; - } - - return IVAS_ERR_OK; -} -#endif - - static ivas_error initSbaMasaRendering( input_sba *inputSba, int32_t inSampleRate ) { ivas_error error; -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputSba->crendWrapper, inputSba->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); -#else - ivas_rend_closeCrend( &inputSba->crendWrapper ); -#endif if ( ( error = ivas_dirac_ana_open( &inputSba->hDirAC, inSampleRate ) ) != IVAS_ERR_OK ) { @@ -2848,9 +2606,7 @@ static ivas_error setRendInputActiveSba( rendering_context rendCtx; AUDIO_CONFIG outConfig; input_sba *inputSba; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif inputSba = (input_sba *) input; rendCtx = inputSba->base.ctx; @@ -2861,35 +2617,21 @@ static ivas_error setRendInputActiveSba( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = allocateInputBaseBufferData( &inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) -#else - if ( ( error = allocateInputBaseBufferData( &inputSba->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) -#endif { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT initRendInputBase( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH ); -#else - initRendInputBase( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData, MAX_BUFFER_LENGTH ); -#endif setZeroPanMatrix( inputSba->hoaDecMtx ); -#ifdef SPLIT_REND_WITH_HEAD_ROT inputSba->crendWrapper = NULL; for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { initRotGains( inputSba->rot_gains_prev[pos_idx] ); } inputSba->cldfbRendWrapper.hHrtfFastConv = hrtfs->hHrtfFastConv; -#else - inputSba->crendWrapper = NULL; - inputSba->hDirAC = NULL; - initRotGains( inputSba->rot_gains_prev ); -#endif if ( outConfig == IVAS_AUDIO_CONFIG_MASA1 || outConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -2908,38 +2650,6 @@ static ivas_error setRendInputActiveSba( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static void clearInputSplitRend( - input_split_post_rend *inputSplitRend ) -{ - rendering_context rendCtx; - - rendCtx = inputSplitRend->base.ctx; - - freeInputBaseBufferData( &inputSplitRend->bufferData ); - - initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); - - if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) - { - ivas_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); - } - - if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) - { - ivas_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); - } - - if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) - { - IVAS_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); - } - - return; -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ - - static void clearInputSba( input_sba *inputSba ) { @@ -2952,16 +2662,12 @@ static void clearInputSba( initRendInputBase( &inputSba->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); /* Free input's internal handles */ -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_rend_closeCrend( &inputSba->crendWrapper, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ); if ( inputSba->cldfbRendWrapper.hCldfbRend != NULL ) { ivas_rend_closeCldfbRend( &inputSba->cldfbRendWrapper ); } -#else - ivas_rend_closeCrend( &inputSba->crendWrapper ); -#endif ivas_dirac_ana_close( &( inputSba->hDirAC ) ); @@ -3040,62 +2746,6 @@ static void clearInputMasa( return; } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error initSplitRend( - SPLIT_REND_WRAPPER *pSplitRendWrapper, - IVAS_REND_AudioBuffer *pSplitRendEncBuffer, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - IVAS_REND_HeadRotData headRotData, - const int32_t outputSampleRate, - const AUDIO_CONFIG outConfig, - const int16_t cldfb_in_flag, - const int16_t num_subframes ) -{ - ivas_error error; - IVAS_REND_AudioBufferConfig bufConfig; - - if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - ivas_renderSplitGetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); - } - else if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) - { - ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); - } - - if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - - /*allocate for CLDFB in and change to TD during process if needed*/ - bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; - bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; - bufConfig.is_cldfb = 1; - pSplitRendEncBuffer->config = bufConfig; - - if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - } - else - { - IVAS_REND_AudioBufferConfig bufConfig2; - - bufConfig2.numSamplesPerChannel = 0; - bufConfig2.numChannels = 0; - bufConfig2.is_cldfb = 0; - pSplitRendEncBuffer->config = bufConfig2; - pSplitRendEncBuffer->data = NULL; - } - - return IVAS_ERR_OK; -} -#endif - /*------------------------------------------------------------------------- * IVAS_REND_Open() @@ -3113,9 +2763,7 @@ ivas_error IVAS_REND_Open( const int16_t num_subframes ) { int16_t i; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t j; -#endif IVAS_REND_HANDLE hIvasRend; ivas_error error; int16_t numOutChannels; @@ -3190,10 +2838,8 @@ ivas_error IVAS_REND_Open( } /* Initialize inputs */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_init_split_rend_handles( &hIvasRend->splitRendWrapper ); + isar_init_split_rend_handles( &hIvasRend->splitRendWrapper ); hIvasRend->splitRendEncBuffer.data = NULL; -#endif for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { @@ -3202,13 +2848,11 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsIsm[i].crendWrapper = NULL; hIvasRend->inputsIsm[i].hReverb = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( j = 0; j < (int16_t) ( sizeof( hIvasRend->inputsIsm[i].splitTdRendWrappers ) / sizeof( *hIvasRend->inputsIsm[i].splitTdRendWrappers ) ); ++j ) { hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hBinRendererTd = NULL; hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hHrtfTD = NULL; } -#endif hIvasRend->inputsIsm[i].bufferData = NULL; hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain; @@ -3228,13 +2872,11 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain; hIvasRend->inputsMc[i].hMcMasa = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( j = 0; j < (int16_t) ( sizeof( hIvasRend->inputsMc[i].splitTdRendWrappers ) / sizeof( *hIvasRend->inputsMc[i].splitTdRendWrappers ) ); ++j ) { hIvasRend->inputsMc[i].splitTdRendWrappers[j].hBinRendererTd = NULL; hIvasRend->inputsMc[i].splitTdRendWrappers[j].hHrtfTD = NULL; } -#endif } for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) @@ -3242,10 +2884,8 @@ ivas_error IVAS_REND_Open( initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); hIvasRend->inputsSba[i].crendWrapper = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend = NULL; hIvasRend->inputsSba[i].cldfbRendWrapper.hHrtfFastConv = NULL; -#endif hIvasRend->inputsSba[i].bufferData = NULL; hIvasRend->inputsSba[i].hDirAC = NULL; } @@ -3260,19 +2900,6 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMasa[i].hMasaExtRend = NULL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - - ivas_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); - -#ifdef SPLIT_REND_WITH_HEAD_ROT - hIvasRend->splitRendBFI = 0; -#endif - hIvasRend->inputsSplitPost[i].bufferData = NULL; - } -#endif hIvasRend->hHrtfs.hHrtfFastConv = NULL; hIvasRend->hHrtfs.hHrtfParambin = NULL; @@ -3556,15 +3183,6 @@ static ivas_error getInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; - break; -#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3630,15 +3248,6 @@ static ivas_error getConstInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; - break; -#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3698,7 +3307,12 @@ static ivas_error findFreeInputSlot( } -#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * Function getCldfbRendFlag() + * + * + *------------------------------------------------------------------------*/ + static int16_t getCldfbRendFlag( IVAS_REND_HANDLE hIvasRend, /* i : Renderer handle */ const IVAS_REND_AudioConfigType new_configType ) @@ -3731,7 +3345,7 @@ static int16_t getCldfbRendFlag( { isCldfbRend = 0; } - else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) + else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) { isCldfbRend = 1; } @@ -3740,25 +3354,65 @@ static int16_t getCldfbRendFlag( return isCldfbRend; } +/*------------------------------------------------------------------------- + * Function ivas_pre_rend_init() + * + * + *------------------------------------------------------------------------*/ -static void closeSplitRend( +static ivas_error ivas_pre_rend_init( SPLIT_REND_WRAPPER *pSplitRendWrapper, - IVAS_REND_AudioBuffer *pSplitRendEncBuffer ) + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t cldfb_in_flag, + const int16_t num_subframes ) { - ivas_split_renderer_close( pSplitRendWrapper ); + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; - if ( pSplitRendEncBuffer->data != NULL ) + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - free( pSplitRendEncBuffer->data ); - pSplitRendEncBuffer->data = NULL; - } + if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + ISAR_PRE_REND_GetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + else if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + isar_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } - pSplitRendEncBuffer->config.numChannels = 0; - pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + if ( ( error = ISAR_PRE_REND_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } - return; -} -#endif + /*allocate for CLDFB in and change to TD during process if needed*/ + bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; + bufConfig.is_cldfb = 1; + pSplitRendEncBuffer->config = bufConfig; + + if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + else + { + IVAS_REND_AudioBufferConfig bufConfig2; + + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data = NULL; + } + + return IVAS_ERR_OK; +} /*-------------------------------------------------------------------* @@ -3786,23 +3440,16 @@ ivas_error IVAS_REND_AddInput( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && hIvasRend->splitRendEncBuffer.data == NULL && hIvasRend->hRendererConfig != NULL ) { int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } } -#endif switch ( getAudioConfigType( inConfig ) ) { @@ -3830,14 +3477,6 @@ ivas_error IVAS_REND_AddInput( inputStructSize = sizeof( *hIvasRend->inputsMasa ); activateInput = setRendInputActiveMasa; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; - inputsArray = hIvasRend->inputsSplitPost; - inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); - activateInput = setRendInputActiveSplitPostRend; - break; -#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -3908,11 +3547,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) -#else - if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif { if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, @@ -4106,11 +3741,6 @@ ivas_error IVAS_REND_RemoveInput( case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: clearInputMasa( (input_masa *) inputBase ); break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - clearInputSplitRend( (input_split_post_rend *) inputBase ); - break; -#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -4233,10 +3863,9 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->inputsSba[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( hIvasRend->splitRendWrapper.hBinHrSplitPreRend != NULL ) { - if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; } @@ -4253,7 +3882,6 @@ ivas_error IVAS_REND_GetDelay( max_latency_ns = max( max_latency_ns, latency_ns ); } else -#endif { latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; max_latency_ns = max( max_latency_ns, latency_ns ); @@ -4261,31 +3889,6 @@ ivas_error IVAS_REND_GetDelay( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) - { - if ( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) - { - latency_ns = 0; - if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) - { - int32_t lc3plusDelaySamples; - IVAS_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); - latency_ns = (int32_t) roundf( lc3plusDelaySamples * 1000000000.f / *timeScale ); - } - if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - latency_ns += IVAS_FB_DEC_DELAY_NS; - } - else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) - { - latency_ns += IVAS_FB_DEC_DELAY_NS; - } - max_latency_ns = max( max_latency_ns, latency_ns ); - } - } -#endif - for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) { if ( hIvasRend->inputsMasa[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) @@ -4316,9 +3919,7 @@ ivas_error IVAS_REND_FeedInputAudio( ivas_error error; input_base *inputBase; int16_t numInputChannels; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t cldfb2tdSampleFact; -#endif /* Validate function arguments */ if ( hIvasRend == NULL || inputAudio.data == NULL ) @@ -4326,14 +3927,10 @@ ivas_error IVAS_REND_FeedInputAudio( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef SPLIT_REND_WITH_HEAD_ROT cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1; if ( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) || ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) ) -#else - if ( inputAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel ) -#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); } @@ -4343,15 +3940,10 @@ ivas_error IVAS_REND_FeedInputAudio( return IVAS_ERR_WRONG_NUM_CHANNELS; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) -#else - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && - inputAudio.config.numSamplesPerChannel * 1000 != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) -#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } @@ -4380,11 +3972,7 @@ ivas_error IVAS_REND_FeedInputAudio( mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); -#ifdef SPLIT_REND_WITH_HEAD_ROT inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact; -#else - inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel; -#endif return IVAS_ERR_OK; } @@ -4586,20 +4174,22 @@ int16_t IVAS_REND_GetRenderConfig( mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.splitRendBitRate = ISAR_MAX_SPLIT_REND_BITRATE; hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; hRCout->split_rend_config.codec_delay_ms = 0; + hRCout->split_rend_config.isar_frame_size_ms = 20; hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; -#endif + hRCout->split_rend_config.lc3plus_highres = 0; hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; + mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); + return IVAS_ERR_OK; } @@ -4616,9 +4206,12 @@ int16_t IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; -#ifdef SPLIT_REND_WITH_HEAD_ROT + uint16_t i; + input_ism *pIsmInput; + input_masa *pMasaInput; + input_mc *pMcInput; + input_sba *pSbaInput; ivas_error error; -#endif if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { @@ -4637,6 +4230,7 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); + mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); hRenderConfig->roomAcoustics.use_er = 0; if ( renderConfig.roomAcoustics.use_er == 1 ) @@ -4649,79 +4243,135 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - hRenderConfig->split_rend_config = renderConfig.split_rend_config; - /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ - if ( hRenderConfig->split_rend_config.dof == 0 ) + /* Re-initialize reverb instance if already available */ + /* ISM inputs */ + for ( i = 0, pIsmInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pIsmInput ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + if ( pIsmInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + if ( pIsmInput->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pIsmInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend[0] != NULL ) + { + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } } - hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; - - if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + /* MASA inputs */ + for ( i = 0, pMasaInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pMasaInput ) { - return error; + if ( pMasaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMasaInput->hMasaExtRend != NULL ) + { + if ( pMasaInput->hMasaExtRend->hDiracDecBin[0] != NULL && pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( pMasaInput->hMasaExtRend->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRenderConfig->roomAcoustics ), *pMasaInput->base.ctx.pOutSampleRate, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } } - /* Must re-initialize split rendering config in case renderer config is updated after adding renderer inputs */ - /* if its not initialized yet then no need to re-initialize, initialization will happen while adding inputs*/ - if ( hIvasRend->splitRendEncBuffer.data != NULL && hIvasRend->hRendererConfig != NULL ) + /* Multi-channel inputs */ + for ( i = 0, pMcInput = hIvasRend->inputsMc; i < RENDERER_MAX_MC_INPUTS; ++i, ++pMcInput ) { - int16_t cldfb_in_flag; - cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); - - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + if ( pMcInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) { - return error; + /* Skip inactive inputs */ + continue; } - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + if ( pMcInput->hReverb != NULL ) { - return error; + if ( ( error = ivas_reverb_open( &pMcInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend[0] && pMcInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } } } -#endif - return IVAS_ERR_OK; -} - - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-------------------------------------------------------------------* - * IVAS_REND_FeedSplitBinauralBitstream() - * - * - *-------------------------------------------------------------------*/ + /* SBA inputs */ + for ( i = 0, pSbaInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pSbaInput ) + { + if ( pSbaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } -ivas_error IVAS_REND_FeedSplitBinauralBitstream( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ -) -{ - ivas_error error; - input_base *inputBase; - input_split_post_rend *inputSplitPostRend; + if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend[0] != NULL && pSbaInput->crendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } - /* Validate function arguments */ - if ( hIvasRend == NULL || hBits == NULL ) + hRenderConfig->split_rend_config = renderConfig.split_rend_config; + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } - if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; + + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } - inputSplitPostRend = (input_split_post_rend *) inputBase; - inputSplitPostRend->hBits = hBits; + /* Must re-initialize split rendering config in case renderer config is updated after adding renderer inputs */ + /* if its not initialized yet then no need to re-initialize, initialization will happen while adding inputs*/ + if ( hIvasRend->splitRendEncBuffer.data != NULL && hIvasRend->hRendererConfig != NULL ) + { + int16_t cldfb_in_flag; + cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + + if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } return IVAS_ERR_OK; } -#endif /*-------------------------------------------------------------------* @@ -4731,13 +4381,11 @@ ivas_error IVAS_REND_FeedSplitBinauralBitstream( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ - const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ -#endif - const int16_t sf_idx /* i : subframe index */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const int16_t sf_idx /* i : subframe index */ ) { int16_t i; @@ -4793,9 +4441,7 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->headRotData.Pos[sf_idx] = Pos; -#ifdef SPLIT_REND_WITH_HEAD_ROT hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; -#endif return IVAS_ERR_OK; } @@ -4847,7 +4493,6 @@ ivas_error IVAS_REND_DisableHeadRotation( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*-------------------------------------------------------------------* * IVAS_REND_SetSplitRendBFI() * @@ -4855,14 +4500,14 @@ ivas_error IVAS_REND_DisableHeadRotation( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetSplitRendBFI( - IVAS_REND_HANDLE hIvasRend, - const int16_t bfi ) + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : bad frame indicator */ +) { hIvasRend->splitRendBFI = bfi; return IVAS_ERR_OK; } -#endif /*-------------------------------------------------------------------* @@ -5459,7 +5104,7 @@ static ivas_error renderIsmToBinaural( return IVAS_ERR_OK; } -#ifdef SPLIT_REND_WITH_HEAD_ROT + static int16_t getNumSubframesInBuffer( const IVAS_REND_AudioBuffer *buffer, const int32_t sampleRate ) @@ -5474,7 +5119,7 @@ static int16_t getNumSubframesInBuffer( return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES * cldfb2tdSampleFact ) ); } -#endif + static ivas_error renderIsmToBinauralRoom( input_ism *ismInput, @@ -5620,16 +5265,9 @@ static ivas_error renderIsmToBinauralRoom( mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); } - /* render 7_1_4 with BRIRs */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, *ismInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, - NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) - -#endif { return error; } @@ -5810,7 +5448,6 @@ static ivas_error renderIsmToSba( } -#ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error renderIsmToSplitBinaural( input_ism *ismInput, const IVAS_REND_AudioBuffer outAudio ) @@ -5837,7 +5474,7 @@ static ivas_error renderIsmToSplitBinaural( pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( i = 1; i < pCombinedOrientationData->num_subframes; ++i ) { @@ -5910,7 +5547,6 @@ static ivas_error renderIsmToSplitBinaural( /* Encoding to split rendering bitstream done at a higher level */ return IVAS_ERR_OK; } -#endif static void renderIsmToMasa( @@ -5973,12 +5609,10 @@ static ivas_error renderInputIsm( case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: error = renderIsmToBinauralRoom( ismInput, outAudio ); break; -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: error = renderIsmToSplitBinaural( ismInput, outAudio ); break; -#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: error = renderIsmToBinauralReverb( ismInput, outAudio ); break; @@ -6033,15 +5667,11 @@ static ivas_error renderActiveInputsIsm( static ivas_error renderLfeToBinaural( const input_mc *mcInput, -#ifdef SPLIT_REND_WITH_HEAD_ROT const AUDIO_CONFIG outConfig, -#endif IVAS_REND_AudioBuffer outAudio ) { int16_t lfe_idx; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pose_idx, num_poses; -#endif float gain; int16_t ear_idx; float tmpLfeBuffer[MAX_BUFFER_LENGTH_PER_CHANNEL]; @@ -6049,11 +5679,7 @@ static ivas_error renderLfeToBinaural( const float *lfeInput; float *writePtr; -#ifdef SPLIT_REND_WITH_HEAD_ROT assert( ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && "Must be binaural output" ); -#else - assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); -#endif push_wmops( "renderLfeToBinaural" ); @@ -6091,7 +5717,6 @@ static ivas_error renderLfeToBinaural( /* Save remaining LFE samples of current frame for next frame */ mvr2r( lfeInput + num_cpy_smpl_cur_frame, mcInput->lfeDelayBuffer, num_cpy_smpl_prev_frame ); -#ifdef SPLIT_REND_WITH_HEAD_ROT /* Copy LFE to left and right binaural channels for all poses */ if ( mcInput->base.ctx.pSplitRendWrapper != NULL ) { @@ -6110,14 +5735,6 @@ static ivas_error renderLfeToBinaural( v_add( writePtr, tmpLfeBuffer, writePtr, frame_size ); } } -#else /* SPLIT_REND_WITH_HEAD_ROT */ - /* Copy LFE to left and right ears */ - for ( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx ) - { - writePtr = getSmplPtr( outAudio, ear_idx, 0 ); - v_add( writePtr, tmpLfeBuffer, writePtr, frame_size ); - } -#endif /* SPLIT_REND_WITH_HEAD_ROT */ pop_wmops(); @@ -6181,11 +5798,7 @@ static ivas_error renderMcToBinaural( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) -#else - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -6199,13 +5812,8 @@ static ivas_error renderMcToBinaural( } /* call CREND */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, - NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -6213,12 +5821,7 @@ static ivas_error renderMcToBinaural( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) -#else - if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) -#endif - { return error; } @@ -6284,13 +5887,7 @@ static ivas_error renderMcToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, -#ifdef SPLIT_REND_WITH_HEAD_ROT - mcInput->rot_gains_prev[0], -#else - mcInput->rot_gains_prev, -#endif - mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -6304,13 +5901,8 @@ static ivas_error renderMcToBinauralRoom( } /* call CREND */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, - NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -6318,11 +5910,7 @@ static ivas_error renderMcToBinauralRoom( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) -#else - if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -6378,13 +5966,7 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, -#ifdef SPLIT_REND_WITH_HEAD_ROT - mcInput->rot_gains_prev[0], -#else - mcInput->rot_gains_prev, -#endif - mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -6410,24 +5992,15 @@ static ivas_error renderMcCustomLsToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, - NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) -#else - if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -6501,7 +6074,6 @@ static void renderMcToMasa( } -#ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error renderMcToSplitBinaural( input_mc *mcInput, const AUDIO_CONFIG outConfig, @@ -6536,7 +6108,7 @@ static ivas_error renderMcToSplitBinaural( /* save current head positions */ pCombinedOrientationDataLocal = *mcInput->base.ctx.pCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; ++sf ) { @@ -6610,7 +6182,6 @@ static ivas_error renderMcToSplitBinaural( * 4. LFE mixing * 5. tmpSplitBinBuffer accumulated to outBuffer */ - /* copy input for in-place rotation */ set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); @@ -6659,7 +6230,6 @@ static ivas_error renderMcToSplitBinaural( pop_wmops(); return IVAS_ERR_OK; } -#endif static ivas_error renderInputMc( @@ -6711,12 +6281,10 @@ static ivas_error renderInputMc( error = renderMcToBinauralRoom( mcInput, outConfig, outAudio ); } break; -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: error = renderMcToSplitBinaural( mcInput, outConfig, outAudio ); break; -#endif default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } @@ -6797,332 +6365,6 @@ static void renderSbaToSba( return; } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error splitBinLc3plusDecode( - SPLIT_POST_REND_WRAPPER *hSplitBin, - IVAS_SPLIT_REND_BITS_HANDLE bits, - float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k], - IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction ) -{ - ivas_error error; - float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; - int32_t lc3plusBitrateId, lc3plusBitstreamSize; - - push_wmops( "splitBinLc3plusDecode" ); - assert( hSplitBin->hLc3plusDec != NULL ); - - /* Find next byte boundary */ - while ( bits->bits_read % 8 != 0 ) - { - ++bits->bits_read; - } - /* Read LC3plus bitstream size info */ - lc3plusBitrateId = ivas_split_rend_bitstream_read_int32( bits, 8 ); - lc3plusBitstreamSize = ivas_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); - - for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) - { - channel_ptrs[i] = outputBuffer[i]; - } - - if ( ( error = IVAS_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) - { - return error; - } - - pop_wmops(); - return IVAS_ERR_OK; -} - - -static ivas_error renderSplitBinauralWithPostRot( - input_split_post_rend *splitBinInput, - IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI ) -{ - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - ivas_error error; - float Cldfb_RealBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t sf_idx, ch_idx; - IVAS_SPLIT_REND_BITS_DATA bits; - float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; - COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; - SPLIT_POST_REND_WRAPPER *hSplitBin; - int8_t isPostRendInputCldfb; - int16_t chnlIdx, slotIdx, smplIdx; - int16_t preRendFrameSize_ms; - int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; - int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; - float *readPtr, *writePtr; - LC3PLUS_CONFIG config; - int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; - - isPostRendInputCldfb = 0; - push_wmops( "renderSplitBinauralWithPostRot" ); - error = IVAS_ERR_OK; - - pCombinedOrientationData = *splitBinInput->base.ctx.pCombinedOrientationData; - hSplitBin = &splitBinInput->splitPostRendWrapper; - convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); - - config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; - if ( pCombinedOrientationData->num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES ) - { - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) - { - config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * pCombinedOrientationData->num_subframes : 20000; - } - else - { - config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; - } - iNumLCLDIterationsPerFrame = 1; - } - else - { - config.ivas_frame_duration_us = 20000; - } - - if ( bits.codec_frame_size_ms > 0 ) - { - iNumLCLDIterationsPerFrame = (int16_t) config.ivas_frame_duration_us / ( 1000 * bits.codec_frame_size_ms ); - iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); - iNumBlocksPerFrame = CLDFB_NO_COL_MAX * bits.codec_frame_size_ms / 20; - } - else - { - iNumLCLDIterationsPerFrame = 1; - iNumBlocksPerFrame = CLDFB_NO_COL_MAX; - } - - config.channels = BINAURAL_CHANNELS; - config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; - - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) - { - if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) - { - if ( ( error = IVAS_LC3PLUS_DEC_Open( config, - &splitBinInput->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / pCombinedOrientationData->num_subframes; - for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) - { - QuaternionsPost[sf_idx] = pCombinedOrientationData->Quaternions[sf_idx]; - } - - - if ( !SplitRendBFI ) - { - hSplitBin->first_good_frame_received = 1; - } - - if ( hSplitBin->first_good_frame_received == 1 ) - { - if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - if ( !SplitRendBFI ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); -#else - ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); -#endif - } - } - - /*copy pose correction after MD is parsed*/ - hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; - - /* decode audio */ - if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) - { - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - isPostRendInputCldfb = 1; - } - preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000; - - numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); - - outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; - numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; - - for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) - { - if ( splitBinInput->numCachedSamples == 0 ) - { - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - ivas_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); - - /* copy data over to 5ms buffer */ - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) - { - for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) - { - mvr2r( Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); - } - } - - /* cache the remaining 15ms */ - splitBinInput->numCachedSamples = numColPerChannelCacheSize; - writePtr = splitBinInput->bufferData; - for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) - { - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; - } - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; - } - } - } - } - else - { - if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, bits.pose_correction ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* cache the remaining 15ms */ - splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; - mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); - mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); - } - } - else - { - /* copy from cache */ - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); - readPtr = splitBinInput->bufferData; - isPostRendInputCldfb = 1; - - readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; - for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) - { - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; - } - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; - } - } - } - - splitBinInput->numCachedSamples -= outBufNumColPerChannel; - } - else - { - int16_t readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples; - mvr2r( splitBinInput->bufferData + readOffset, &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - mvr2r( splitBinInput->bufferData + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; - } - } - } - } - else - { - copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); - if ( splitBinInput->numCachedSamples == 0 ) - { - preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000; - numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); - numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; - splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; - } - else - { - splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; - } - } - - /* apply pose correction if enabled */ - for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) - { - if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) - { - /* 0DOF with LCLD codec requires CLDFB synthesis */ - int16_t slot_idx; - - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) - { - float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; - - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; - } - - cldfbSynthesis( RealBuffer, - ImagBuffer, - &( tmpCrendBuffer[ch_idx][sf_idx * outBufNumSamplesPerChannel] ), - hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); - } - } - else if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - mvr2r( &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[0], outBufNumSamplesPerChannel ); - mvr2r( &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[1], outBufNumSamplesPerChannel ); - - ivas_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb ); - - mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - } - } - } - else - { - if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) - { - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) - { - set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); - } - } - else - { - copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); - } - } - - convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); - accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); - - pop_wmops(); - return error; -} - static ivas_error renderSbaToMultiBinaural( input_sba *sbaInput, @@ -7148,7 +6390,7 @@ static ivas_error renderSbaToMultiBinaural( pCombinedOrientationDataLocal = *sbaInput->base.ctx.pCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; sf++ ) { @@ -7224,7 +6466,7 @@ static ivas_error renderSbaToMultiBinaural( } -static ivas_error renderSbaToMultiBinauralCldfb( +static void renderSbaToMultiBinauralCldfb( input_sba *sbaInput, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], @@ -7239,7 +6481,7 @@ static ivas_error renderSbaToMultiBinauralCldfb( ivas_rend_CldfbMultiBinRendProcess( sbaInput->cldfbRendWrapper.hCldfbRend, sbaInput->base.ctx.pCombinedOrientationData, &sbaInput->base.ctx.pSplitRendWrapper->multiBinPoseData, Cldfb_RealBuffer, Cldfb_ImagBuffer, Cldfb_Out_Real, Cldfb_Out_Imag, low_res_pre_rend_rot, num_subframes ); - return IVAS_ERR_OK; + return; } @@ -7252,26 +6494,19 @@ static ivas_error renderSbaToSplitBinaural( ivas_error error; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - int16_t low_res_pre_rend_rot; - - low_res_pre_rend_rot = 1; push_wmops( "renderSbaToSplitBinaural" ); - error = IVAS_ERR_OK; - if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { - if ( ( renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot, - getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) - { - return error; - } + renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 1, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ); accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); } else { - if ( ( renderSbaToMultiBinaural( sbaInput, outConfig, tmpCrendBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = renderSbaToMultiBinaural( sbaInput, outConfig, tmpCrendBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -7280,9 +6515,8 @@ static ivas_error renderSbaToSplitBinaural( } pop_wmops(); - return error; + return IVAS_ERR_OK; } -#endif static ivas_error renderSbaToBinaural( @@ -7300,22 +6534,17 @@ static ivas_error renderSbaToBinaural( int16_t subframe_idx; push_wmops( "renderSbaToBinaural" ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - if ( ( error = renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 0, - getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) - { - return error; - } + renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 0, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ); accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); } else -#endif { for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { @@ -7345,13 +6574,8 @@ static ivas_error renderSbaToBinaural( /* copy input for in-place rotation */ mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev[0], tmpRotBuffer ) ) != IVAS_ERR_OK ) -#else - if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, - sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev, tmpRotBuffer ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -7365,13 +6589,8 @@ static ivas_error renderSbaToBinaural( } /* call CREND */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, - NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -7433,13 +6652,7 @@ static ivas_error renderSbaToBinauralRoom( mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, - sbaInput->base.ctx.pCombinedOrientationData, -#ifdef SPLIT_REND_WITH_HEAD_ROT - sbaInput->rot_gains_prev[0], -#else - sbaInput->rot_gains_prev, -#endif - tmpRotBuffer ) ) != IVAS_ERR_OK ) + sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev[0], tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -7466,13 +6679,8 @@ static ivas_error renderSbaToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, - NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -7490,39 +6698,6 @@ static ivas_error renderSbaToBinauralRoom( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error renderInputSplitBin( - input_split_post_rend *splitBinInput, - const AUDIO_CONFIG outConfig, - IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI ) -{ - ivas_error error; - IVAS_REND_AudioBuffer inAudio; - - inAudio = splitBinInput->base.inputBuffer; - - splitBinInput->base.numNewSamplesPerChannel = 0; - - /* Apply input gain to new audio */ - v_multc( inAudio.data, - splitBinInput->base.gain, - inAudio.data, - inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); /* TODO: the output buffer is empty at this point, should be moved to a point after decoding the split bitstream */ - switch ( outConfig ) - { - case IVAS_AUDIO_CONFIG_BINAURAL: - error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI ); - break; - default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; - } - - return error; -} -#endif - - static void renderSbaToMasa( input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) @@ -7546,20 +6721,14 @@ static ivas_error renderInputSba( { ivas_error error; IVAS_REND_AudioBuffer inAudio; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t cldfb2tdSampleFact; -#endif error = IVAS_ERR_OK; inAudio = sbaInput->base.inputBuffer; -#ifdef SPLIT_REND_WITH_HEAD_ROT cldfb2tdSampleFact = outAudio.config.is_cldfb ? 2 : 1; if ( ( sbaInput->base.numNewSamplesPerChannel * cldfb2tdSampleFact != outAudio.config.numSamplesPerChannel ) && ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) -#else - if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) -#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } @@ -7582,12 +6751,10 @@ static ivas_error renderInputSba( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: error = renderSbaToSplitBinaural( sbaInput, outConfig, outAudio ); break; -#endif case IVAS_AUDIO_CONFIG_BINAURAL: error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); break; @@ -7610,34 +6777,6 @@ static ivas_error renderInputSba( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error renderActiveInputsSplitBin( - IVAS_REND_HANDLE hIvasRend, - IVAS_REND_AudioBuffer outAudio ) -{ - int16_t i; - input_split_post_rend *pCurrentInput; - ivas_error error; - - for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) - { - if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) - { - /* Skip inactive inputs */ - continue; - } - - if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - return IVAS_ERR_OK; -} -#endif - - static ivas_error renderActiveInputsSba( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) @@ -7845,11 +6984,9 @@ static ivas_error renderInputMasa( int16_t maxBin; float *tmpBuffer[MAX_OUTPUT_CHANNELS]; float tmpBuffer_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t cldfb2tdSampleFact; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; -#endif if ( !masaInput->metadataHasBeenFed ) { @@ -7857,13 +6994,9 @@ static ivas_error renderInputMasa( } inAudio = masaInput->base.inputBuffer; -#ifdef SPLIT_REND_WITH_HEAD_ROT cldfb2tdSampleFact = outAudio.config.is_cldfb ? 2 : 1; if ( ( masaInput->base.numNewSamplesPerChannel * cldfb2tdSampleFact != outAudio.config.numSamplesPerChannel ) && ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) -#else - if ( masaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) -#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } @@ -7895,7 +7028,6 @@ static ivas_error renderInputMasa( num_subframes = (int16_t) ( masaInput->base.inputBuffer.config.numSamplesPerChannel / ( *masaInput->base.ctx.pOutSampleRate / ( IVAS_NUM_FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { /* split rendering. use the combined of the first subframe in all subframes */ @@ -7923,7 +7055,6 @@ static ivas_error renderInputMasa( else { /* non-split path */ -#endif switch ( masaInput->hMasaExtRend->renderer_type ) { case RENDERER_DIRAC: @@ -7934,11 +7065,7 @@ static ivas_error renderInputMasa( case RENDERER_BINAURAL_PARAMETRIC: case RENDERER_BINAURAL_PARAMETRIC_ROOM: copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes, NULL, NULL, NULL ); -#else - ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes ); -#endif break; case RENDERER_DISABLE: break; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ @@ -7947,9 +7074,7 @@ static ivas_error renderInputMasa( } accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif } return IVAS_ERR_OK; @@ -8159,21 +7284,15 @@ ivas_error IVAS_REND_SetIsmMetadataDelay( *-------------------------------------------------------------------*/ static ivas_error getSamplesInternal( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */, + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/ -#else - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ -#endif ) { ivas_error error; int16_t numOutChannels; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t cldfb2tdSampleFact; IVAS_REND_AudioBuffer outAudioOrig; -#endif /* Validate function arguments */ if ( hIvasRend == NULL || outAudio.data == NULL ) @@ -8181,14 +7300,10 @@ static ivas_error getSamplesInternal( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef SPLIT_REND_WITH_HEAD_ROT cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1; if ( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) -#else - if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) -#endif { return IVAS_ERR_INVALID_BUFFER_SIZE; } @@ -8198,15 +7313,10 @@ static ivas_error getSamplesInternal( return IVAS_ERR_WRONG_NUM_CHANNELS; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) -#else - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && - outAudio.config.numSamplesPerChannel * 1000 != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) -#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } @@ -8247,11 +7357,7 @@ static ivas_error getSamplesInternal( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#else - if ( numOutChannels != outAudio.config.numChannels ) -#endif { return IVAS_ERR_WRONG_NUM_CHANNELS; } @@ -8259,7 +7365,6 @@ static ivas_error getSamplesInternal( /* Clear original output buffer */ set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); -#ifdef SPLIT_REND_WITH_HEAD_ROT outAudioOrig = outAudio; /* Use internal buffer if outputting split rendering bitstream */ if ( ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || @@ -8268,13 +7373,12 @@ static ivas_error getSamplesInternal( int16_t num_poses_orig; num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; outAudio = hIvasRend->splitRendEncBuffer; - ivas_renderSplitGetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); /* Clear output buffer for split rendering bitstream */ set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); } -#endif if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) { @@ -8296,25 +7400,9 @@ static ivas_error getSamplesInternal( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) - { - return error; - } -#else - -#ifndef DISABLE_LIMITER -#ifdef DEBUGGING - hIvasRend->numClipping += -#endif - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); -#endif -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - IVAS_SPLIT_REND_BITS_DATA bits; + ISAR_SPLIT_REND_BITS_DATA bits; int16_t cldfb_in_flag; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -8351,8 +7439,21 @@ static ivas_error getSamplesInternal( } } - if ( ( error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, - &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, ro_md_flag ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, + hIvasRend->headRotData.headPositions[0], + hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, + hIvasRend->hRendererConfig->split_rend_config.codec, + hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms, + hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, + &bits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), + tmpBinaural, + 1, + cldfb_in_flag, + ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, + ro_md_flag ) ) != IVAS_ERR_OK ) { return error; } @@ -8367,9 +7468,7 @@ static ivas_error getSamplesInternal( accumulate2dArrayToBuffer( tmpBinaural_buff, &outAudio ); } } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( outAudio.config.is_cldfb == 0 ) { #ifndef DISABLE_LIMITER @@ -8379,7 +7478,6 @@ static ivas_error getSamplesInternal( limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); #endif } -#endif /* update global cominbed orientation start index */ ivas_combined_orientation_update_start_index( hIvasRend->hCombinedOrientationData, outAudio.config.numSamplesPerChannel ); @@ -8400,15 +7498,10 @@ ivas_error IVAS_REND_GetSamples( ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT return getSamplesInternal( hIvasRend, outAudio, NULL ); -#else - return getSamplesInternal( hIvasRend, outAudio ); -#endif } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*-------------------------------------------------------------------* * IVAS_REND_GetSplitBinauralBitstream() * @@ -8425,7 +7518,7 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag; - if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) { hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = outAudio.config.numSamplesPerChannel; } @@ -8442,27 +7535,31 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( /*-------------------------------------------------------------------* - * IVAS_REND_GetSplitBinauralSamples() + * IVAS_REND_GetSplitRendBitstreamHeader() * * *-------------------------------------------------------------------*/ -ivas_error IVAS_REND_GetSplitBinauralSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ - bool *needNewFrame ) +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pIsar_frame_size_ms /* o : pointer to ISAR frame size setting */ +) { - ivas_error error; - - if ( ( error = getSamplesInternal( hIvasRend, outAudio, NULL ) ) != IVAS_ERR_OK ) + if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; + + *pCodec = hIvasRend->hRendererConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms; + *pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms; + *poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode; return IVAS_ERR_OK; } -#endif /*-------------------------------------------------------------------* @@ -8507,22 +7604,14 @@ void IVAS_REND_Close( { clearInputMasa( &hIvasRend->inputsMasa[i] ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); - } -#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); ivas_limiter_close( &hIvasRend->hLimiter ); -#ifdef SPLIT_REND_WITH_HEAD_ROT /* Split binaural rendering */ - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); -#endif + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); closeHeadRotation( hIvasRend ); @@ -8546,7 +7635,6 @@ void IVAS_REND_Close( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*-------------------------------------------------------------------* * IVAS_REND_openCldfb() * @@ -8663,7 +7751,6 @@ void IVAS_REND_cldfbSynthesis_wrapper( return; } -#endif #ifdef DEBUGGING @@ -9175,9 +8262,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( float binCenterFreq, tmpFloat; ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx; -#endif error = IVAS_ERR_OK; @@ -9188,13 +8273,9 @@ static ivas_error ivas_masa_ext_rend_parambin_init( nBins = inputMasa->hMasaExtRend->hSpatParamRendCom->num_freq_bands; renderer_type = inputMasa->hMasaExtRend->renderer_type; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( pos_idx = 0; pos_idx < inputMasa->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; pos_idx++ ) { hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin[pos_idx]; -#else - hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin; -#endif /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ if ( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) @@ -9253,11 +8334,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { mvr2r( ( *phHrtfParambin )->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ -#else - if ( hDiracDecBin->hReverb == NULL ) -#endif { if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRendCfg->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) { @@ -9276,10 +8353,8 @@ static ivas_error ivas_masa_ext_rend_parambin_init( assert( false ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( pos_idx == 0 ) /* open decorrelator only for the main direction */ { -#endif /* Always open frequency domain decorrelator */ ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), @@ -9294,20 +8369,15 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT } -#endif + /* External renderer uses constant regularization factor */ hDiracDecBin->reqularizationFactor = 0.4f; hDiracDecBin->phHrtfParambin = phHrtfParambin; -#ifdef SPLIT_REND_WITH_HEAD_ROT inputMasa->hMasaExtRend->hDiracDecBin[pos_idx] = hDiracDecBin; } -#else - inputMasa->hMasaExtRend->hDiracDecBin = hDiracDecBin; -#endif return error; } @@ -9335,14 +8405,10 @@ static ivas_error initMasaExtRenderer( hMasaExtRend->renderer_type = RENDERER_DISABLE; hMasaExtRend->hDirACRend = NULL; hMasaExtRend->hSpatParamRendCom = NULL; -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) { hMasaExtRend->hDiracDecBin[i] = NULL; } -#else - hMasaExtRend->hDiracDecBin = NULL; -#endif hMasaExtRend->hReverb = NULL; hMasaExtRend->hHrtfParambin = &hrtfs->hHrtfParambin; hMasaExtRend->hVBAPdata = NULL; @@ -9389,10 +8455,8 @@ static ivas_error initMasaExtRenderer( break; case IVAS_AUDIO_CONFIG_BINAURAL: -#ifdef SPLIT_REND_WITH_HEAD_ROT case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: -#endif hMasaExtRend->renderer_type = RENDERER_BINAURAL_PARAMETRIC; break; @@ -9506,7 +8570,6 @@ static void freeMasaExtRenderer( ivas_spat_hSpatParamRendCom_close( &hMasaExtRend->hSpatParamRendCom ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) { if ( hMasaExtRend->hDiracDecBin[i] != NULL ) @@ -9515,12 +8578,6 @@ static void freeMasaExtRenderer( } } -#else - if ( hMasaExtRend->hDiracDecBin != NULL ) - { - ivas_dirac_dec_close_binaural_data( &hMasaExtRend->hDiracDecBin ); - } -#endif if ( hMasaExtRend->hReverb != NULL ) { diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index a670e75af2108c83450e4066dea57a2c43769b23..5cd2b07f617c8ad87911d7381259cbe6220f968d 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -35,6 +35,7 @@ #include "common_api_types.h" #include +#include "ivas_stat_rend.h" /*---------------------------------------------------------------------* * Renderer constants @@ -45,10 +46,6 @@ #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_MAX_INPUT_LFE_CHANNELS 4 -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define RENDERER_MAX_BIN_INPUTS 1 -#endif - /*---------------------------------------------------------------------* * Renderer structures @@ -56,37 +53,22 @@ typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; -typedef struct -{ - int16_t numSamplesPerChannel; - int16_t numChannels; -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t is_cldfb; -#endif -} IVAS_REND_AudioBufferConfig; - -typedef struct -{ - IVAS_REND_AudioBufferConfig config; - float *data; -} IVAS_REND_AudioBuffer; - -#ifdef SPLIT_REND_WITH_HEAD_ROT typedef struct { int32_t bufLenInBytes; int32_t bitsWritten; int32_t bitsRead; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t codec_frame_size_ms; + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; } IVAS_REND_BitstreamBufferConfig; typedef struct { IVAS_REND_BitstreamBufferConfig config; uint8_t *bits; } IVAS_REND_BitstreamBuffer; -#endif typedef struct { @@ -125,13 +107,13 @@ typedef enum _IVAS_REND_COMPLEXITY_LEVEL /* Functions to be called before rendering */ ivas_error IVAS_REND_Open( - IVAS_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ - const int32_t outputSampleRate, /* i : output sampling rate */ - const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ - const bool asHrtfBinary, /* i : load hrtf binary file */ - const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ - const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ - const int16_t num_subframes /* i : number of subframes */ + IVAS_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t num_subframes /* i : number of subframes */ ); /* Note: this will reset custom LFE routings set for any MC input */ @@ -266,11 +248,10 @@ int16_t IVAS_REND_FeedRenderConfig( const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error IVAS_REND_FeedSplitBinauralBitstream( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ + IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ ); ivas_error IVAS_REND_GetSplitBinauralSamples( @@ -284,15 +265,20 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ ); -#endif + +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pIsar_frame_size_ms /* o : pointer to ISAR frame size setting */ +); ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ -#endif + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ const int16_t sf_idx /* i : subframe index */ ); @@ -327,11 +313,10 @@ ivas_error IVAS_REND_SetReferenceVector( const IVAS_VECTOR3 refPos /* i : Reference position */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error IVAS_REND_SetSplitRendBFI( - IVAS_REND_HANDLE hIvasRend, - const int16_t bfi); -#endif + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : bad frame indicator */ +); ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -381,8 +366,8 @@ ivas_error IVAS_REND_GetNumAllObjects( ); ivas_error IVAS_REND_GetSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ ); /* Functions to be called after rendering */ @@ -392,7 +377,6 @@ void IVAS_REND_Close( ); -#ifdef SPLIT_REND_WITH_HEAD_ROT /* Split binaural rendering functions */ ivas_error IVAS_REND_openCldfb( @@ -423,7 +407,6 @@ void IVAS_REND_cldfbSynthesis_wrapper( const int16_t samplesToProcess, /* i : number of processed samples */ IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb /* i : filter bank state */ ); -#endif #ifdef DEBUGGING int32_t IVAS_REND_GetNoCLipping( diff --git a/lib_util/aeid_file_reader.c b/lib_util/aeid_file_reader.c new file mode 100644 index 0000000000000000000000000000000000000000..83dd4b4e1857595b2ec3774484592b1ef69c80f0 --- /dev/null +++ b/lib_util/aeid_file_reader.c @@ -0,0 +1,185 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "aeid_file_reader.h" +#include "ivas_error_utils.h" +#include +#include + +struct aeidFileReader +{ + FILE *aeidFile; + char *file_path; +}; + + +/*-----------------------------------------------------------------------* + * aeidFileReader_open() + * + * Allocate and initialize rotation handle + *-----------------------------------------------------------------------*/ + +ivas_error aeidFileReader_open( + char *aeidFilePath, /* i : aeid file name */ + aeidFileReader **aeidReader /* o : aeidFileReader handle */ +) +{ + aeidFileReader *self; + FILE *aeidFile; + + /* Open trajectory file */ + if ( strlen( aeidFilePath ) < 1 ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + aeidFile = fopen( aeidFilePath, "r" ); + + if ( !aeidFile ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + self = calloc( sizeof( aeidFileReader ), 1 ); + self->aeidFile = aeidFile; + self->file_path = calloc( sizeof( char ), strlen( aeidFilePath ) + 1 ); + strcpy( self->file_path, aeidFilePath ); + + *aeidReader = self; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------* + * aeidFileReading() + * + * Read values from the aeid file + *-----------------------------------------------------------------------*/ + +ivas_error aeidFileReading( + aeidFileReader *aeidReader, /* i : aeidFileReader handle */ + uint16_t *count, /* o : number of sequences */ + uint16_t **pID, /* o : acoustic environment ID data */ + uint16_t **pValidity /* o : duration data */ +) +{ + int32_t id; + int32_t duration; + uint16_t k = 0; + + while ( !feof( aeidReader->aeidFile ) ) + { + if ( fscanf( aeidReader->aeidFile, "%d %d", &id, &duration ) == 2 ) + { + k++; + } + else + { + return IVAS_ERROR( IVAS_ERR_FAILED_FILE_PARSE, "Error while parsing acoustic environment sequence" ); + } + } + + if ( k == 0 ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_FILE_PARSE, "No acoustic environment" ); + } + + if ( NULL == ( *pID = malloc( sizeof( uint16_t ) * k ) ) || + NULL == ( *pValidity = malloc( sizeof( uint16_t ) * k ) ) ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Unable to allocate memory for acoustic environment sequence" ); + } + + *count = k; + + k = 0; + + fseek( aeidReader->aeidFile, 0, SEEK_SET ); + + while ( !feof( aeidReader->aeidFile ) ) + { + if ( fscanf( aeidReader->aeidFile, "%d %d", &id, &duration ) == 2 ) + { + ( *pID )[k] = (uint16_t) id; + ( *pValidity )[k] = (uint16_t) duration; + k++; + } + else + { + return IVAS_ERROR( IVAS_ERR_FAILED_FILE_PARSE, "Error while parsing acoustic environment sequence" ); + } + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------* + * aeidFileReader_close() + * + * Deallocates memory for the aeid handle + *-----------------------------------------------------------------------*/ + +void aeidFileReader_close( + aeidFileReader **aeidReader /* i/o: aeidFileReader handle */ +) +{ + if ( aeidReader == NULL || *aeidReader == NULL ) + { + return; + } + + fclose( ( *aeidReader )->aeidFile ); + free( ( *aeidReader )->file_path ); + free( *aeidReader ); + *aeidReader = NULL; + + return; +} + +/*-----------------------------------------------------------------------* + * aeidFileReader_getFilePath() + * + * + *-----------------------------------------------------------------------*/ + +const char *aeidFileReader_getFilePath( + aeidFileReader *aeidReader /* i : aeidFileReader handle */ +) +{ + if ( aeidReader == NULL ) + { + return NULL; + } + + return aeidReader->file_path; +} diff --git a/lib_util/aeid_file_reader.h b/lib_util/aeid_file_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..c48a8d4122e383fb3982b89dbf3ce5a93bc99ee8 --- /dev/null +++ b/lib_util/aeid_file_reader.h @@ -0,0 +1,87 @@ +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef IVAS_AEID_FILE_READER_H +#define IVAS_AEID_FILE_READER_H + +#include "common_api_types.h" + + +struct aeidFileReader; +typedef struct aeidFileReader aeidFileReader; + +/*-----------------------------------------------------------------------* + * aeidFileReader_open() + * + * Allocate and initialize rotation handle + *-----------------------------------------------------------------------*/ + +ivas_error aeidFileReader_open( + char *aeidFilePath, /* i : aeid file name */ + struct aeidFileReader **aeidReader /* o : aeidFileReader handle */ +); + +/*-----------------------------------------------------------------------* + * aeidFileReading() + * + * Read values from the aeid file + *-----------------------------------------------------------------------*/ + +ivas_error aeidFileReading( + aeidFileReader *aeidReader, /* i : aeidFileReader handle */ + uint16_t *count, /* o : number of sequences */ + uint16_t **pID, /* o : acoustic environment ID data */ + uint16_t **pValidity /* o : duration data */ +); + +/*-----------------------------------------------------------------------* + * aeidFileReader_close() + * + * Deallocates memory for the aeid handle + *-----------------------------------------------------------------------*/ + +void aeidFileReader_close( + aeidFileReader **aeidReader /* i/o: aeidFileReader handle */ +); + +/*-----------------------------------------------------------------------* + * aeidFileReader_getFilePath() + * + * + *-----------------------------------------------------------------------*/ + +const char *aeidFileReader_getFilePath( + aeidFileReader *aeidReader /* i : aeidFileReader handle */ +); + + +#endif /* IVAS_AEID_FILE_READER_H */ diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 813a3dfc27c32c2a3082ca8249920f5aac2e6908..970daa9609fcfafb4ea5445c304a8e47f6646b2b 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -32,10 +32,12 @@ #include "hrtf_file_reader.h" #include +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +#include +#endif #include "prot.h" #include "ivas_prot_rend.h" #include "ivas_prot.h" -#include "ivas_rom_binaural_crend_head.h" /*---------------------------------------------------------------------* * Local structures @@ -63,7 +65,9 @@ typedef struct ivas_hrtfs_file_header_t #define RESAMPLE_FACTOR_16_48 ( 16.0f / 48.0f ) #define RESAMPLE_FACTOR_32_48 ( 32.0f / 48.0f ) - +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +#define DEFAULT_BIN_FILE_FX_FLAG 0x1000 +#endif /*---------------------------------------------------------------------* * Local function declarations *---------------------------------------------------------------------*/ @@ -189,7 +193,11 @@ static ivas_error check_hrtf_binary_header( /* Check the renderer type */ if ( ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_MIXER_CONV ) && ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM ) && ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_FASTCONV ) && ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM ) && +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_PARAMETRIC ) && +#else ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_PARAMETRIC ) && ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM ) && +#endif ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD ) && ( hrtf_header->rend_type != HRTF_READER_RENDERER_BINAURAL_REVERB_ALL ) ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Header of HRTF binary file not compliant (renderer type)" ); @@ -220,6 +228,9 @@ static ivas_error check_hrtf_binary_header( static ivas_error read_hrtf_binary_header( ivas_hrtfs_header_t *hrtf_header, +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t *is_fix_point, +#endif FILE *f_hrtf ) { /* HRTF Header */ @@ -227,9 +238,18 @@ static ivas_error read_hrtf_binary_header( /* Input configuration (4 bytes) : See "BINAURAL_INPUT_AUDIO_CONFIG" */ /* Sampling Frequency (4 bytes) */ /* Raw data size (4 bytes) */ - +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + *is_fix_point = 0; +#endif if ( ( fread( &( hrtf_header->rend_type ), sizeof( int32_t ), 1, f_hrtf ) == 1 ) && ( fread( &( hrtf_header->input_cfg ), sizeof( int32_t ), 1, f_hrtf ) == 1 ) && ( fread( &( hrtf_header->frequency ), sizeof( int32_t ), 1, f_hrtf ) == 1 ) && ( fread( &( hrtf_header->data_size ), sizeof( int32_t ), 1, f_hrtf ) == 1 ) ) { +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( hrtf_header->rend_type & DEFAULT_BIN_FILE_FX_FLAG ) + { + *is_fix_point = 1; + hrtf_header->rend_type = hrtf_header->rend_type - DEFAULT_BIN_FILE_FX_FLAG; + } +#endif return IVAS_ERR_OK; } @@ -249,13 +269,10 @@ static void LoadBSplineBinaryITD( ) { int16_t tmp; - fread( &modelITD->N, sizeof( int16_t ), 1, f_hrtf ); - fread( &modelITD->elevDim2, sizeof( int16_t ), 1, f_hrtf ); fread( &modelITD->elevDim3, sizeof( int16_t ), 1, f_hrtf ); modelITD->elevKSeq_dyn = (float *) malloc( ( modelITD->elevDim3 - 2 ) * sizeof( float ) ); fread( modelITD->elevKSeq_dyn, sizeof( float ), modelITD->elevDim3 - 2, f_hrtf ); - fread( &modelITD->azimDim2, sizeof( int16_t ), 1, f_hrtf ); fread( &modelITD->azimDim3, sizeof( int16_t ), 1, f_hrtf ); modelITD->azimKSeq_dyn = (float *) malloc( ( ( modelITD->azimDim3 + 1 ) / 2 - 2 ) * sizeof( float ) ); /* basis functions are flipped around 180 deg, number of basis functions above/below is (N+1)/2 */ fread( modelITD->azimKSeq_dyn, sizeof( float ), ( modelITD->azimDim3 + 1 ) / 2 - 2, f_hrtf ); @@ -265,8 +282,10 @@ static void LoadBSplineBinaryITD( fread( modelITD->W_dyn, sizeof( float ), tmp, f_hrtf ); /* azimuth */ - fread( modelITD->azimBsLen, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); - fread( modelITD->azimBsStart, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); + modelITD->azimBsLen_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) ); + fread( modelITD->azimBsLen_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); + modelITD->azimBsStart_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) ); + fread( modelITD->azimBsStart_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); fread( &tmp, sizeof( int16_t ), 1, f_hrtf ); @@ -276,8 +295,10 @@ static void LoadBSplineBinaryITD( fread( &modelITD->azimSegSamples, sizeof( int16_t ), 1, f_hrtf ); /* elevation */ - fread( modelITD->elevBsLen, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); - fread( modelITD->elevBsStart, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); + modelITD->elevBsLen_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) ); + fread( modelITD->elevBsLen_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); + modelITD->elevBsStart_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) ); + fread( modelITD->elevBsStart_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); fread( &tmp, sizeof( int16_t ), 1, f_hrtf ); @@ -291,6 +312,10 @@ static void LoadBSplineBinaryITD( modelITD->W = (const float *) modelITD->W_dyn; modelITD->azimBsShape = (const float *) modelITD->azimBsShape_dyn; modelITD->elevBsShape = (const float *) modelITD->elevBsShape_dyn; + modelITD->azimBsLen = (const int16_t *) modelITD->azimBsLen_dyn; + modelITD->azimBsStart = (const int16_t *) modelITD->azimBsStart_dyn; + modelITD->elevBsLen = (const int16_t *) modelITD->elevBsLen_dyn; + modelITD->elevBsStart = (const int16_t *) modelITD->elevBsStart_dyn; return; } @@ -347,20 +372,15 @@ static ivas_error LoadBSplineBinary( return IVAS_ERROR( IVAS_ERR_INVALID_HRTF, "Error: HR filter file had an unsupported sampling rate (%d kHz)", tmp ); } - fread( &model->SplineDegree, sizeof( int16_t ), 1, f_hrtf ); fread( &model->K, sizeof( int16_t ), 1, f_hrtf ); - - fread( &model->elevDim2, sizeof( int16_t ), 1, f_hrtf ); fread( &model->elevDim3, sizeof( int16_t ), 1, f_hrtf ); model->elevKSeq_dyn = (float *) malloc( ( model->elevDim3 - 2 ) * sizeof( float ) ); fread( model->elevKSeq_dyn, sizeof( float ), model->elevDim3 - 2, f_hrtf ); - model->azimDim2_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) ); model->azimDim3_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) ); model->azim_start_idx_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) ); model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ); for ( i = 0; i < model->elevDim3; i++ ) { - fread( &model->azimDim2_dyn[i], sizeof( int16_t ), 1, f_hrtf ); fread( &model->azimDim3_dyn[i], sizeof( int16_t ), 1, f_hrtf ); fread( &model->azim_start_idx_dyn[i], sizeof( int16_t ), 1, f_hrtf ); model->azimKSeq[i] = (float *) malloc( ( model->azimDim3_dyn[i] + 1 ) * sizeof( float ) ); @@ -393,8 +413,10 @@ static ivas_error LoadBSplineBinary( fread( model->azimShapeSampFactor_dyn, sizeof( int16_t ), model->elevDim3, f_hrtf ); /* elevation */ - fread( model->elevBsLen, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); - fread( model->elevBsStart, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); + model->elevBsLen_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) ); + fread( model->elevBsLen_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); + model->elevBsStart_dyn = (int16_t *) malloc( HRTF_MODEL_BSPLINE_NUM_COEFFS * sizeof( int16_t ) ); + fread( model->elevBsStart_dyn, sizeof( int16_t ), HRTF_MODEL_BSPLINE_NUM_COEFFS, f_hrtf ); fread( &tmp, sizeof( int16_t ), 1, f_hrtf ); model->elevBsShape_dyn = (float *) malloc( tmp * sizeof( float ) ); fread( model->elevBsShape_dyn, sizeof( float ), tmp, f_hrtf ); @@ -406,9 +428,10 @@ static ivas_error LoadBSplineBinary( model->AlphaR = (const float *) model->AlphaR_dyn; model->EL = (const float *) model->EL_dyn; model->ER = (const float *) model->ER_dyn; + model->elevBsLen = (const int16_t *) model->elevBsLen_dyn; + model->elevBsStart = (const int16_t *) model->elevBsStart_dyn; model->elevBsShape = (const float *) model->elevBsShape_dyn; model->elevKSeq = (const float *) model->elevKSeq_dyn; - model->azimDim2 = (const int16_t *) model->azimDim2_dyn; model->azimDim3 = (const int16_t *) model->azimDim3_dyn; model->azim_start_idx = (const int16_t *) model->azim_start_idx_dyn; model->azimSegSamples = (const int16_t *) model->azimSegSamples_dyn; @@ -456,6 +479,13 @@ static ivas_error load_reverb_from_binary( int32_t hrtf_data_size_max; char *hrtf_data; int16_t lr_iac_len; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; + int16_t ind; + Word16 factorQ; + Word16 tmp16; + float factorQ_f; +#endif if ( hHrtfStatistics == NULL ) { @@ -493,7 +523,11 @@ static ivas_error load_reverb_from_binary( for ( hrtf_id = 0; ( hrtf_id < hrtfs_file_header.nb_hrtf ) && ( !is_reverb ); hrtf_id++ ) { +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( read_hrtf_binary_header( &hrtf_header, &is_fx, f_hrtf ) != IVAS_ERR_OK ) +#else if ( read_hrtf_binary_header( &hrtf_header, f_hrtf ) != IVAS_ERR_OK ) +#endif { free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "HRTF binary file not compliant (number of HRTF)" ); @@ -528,9 +562,38 @@ static ivas_error load_reverb_from_binary( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for hrtf data" ); } +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx ) + { + fread( &factorQ, sizeof( Word16 ), 1, f_hrtf ); + factorQ_f = powf( 2.f, -1.f * (float) factorQ ); + for ( ind = 0; ind < lr_iac_len; ind++ ) + { + fread( &tmp16, sizeof( Word16 ), 1, f_hrtf ); + hHrtfStatistics->average_energy_l[ind] = factorQ_f * (float) tmp16; + } + for ( ind = 0; ind < lr_iac_len; ind++ ) + { + fread( &tmp16, sizeof( Word16 ), 1, f_hrtf ); + hHrtfStatistics->average_energy_r[ind] = factorQ_f * (float) tmp16; + } + for ( ind = 0; ind < lr_iac_len; ind++ ) + { + fread( &tmp16, sizeof( Word16 ), 1, f_hrtf ); + hHrtfStatistics->inter_aural_coherence[ind] = factorQ_f * (float) tmp16; + } + } + else + { + fread( hHrtfStatistics->average_energy_l, sizeof( const float ), lr_iac_len, f_hrtf ); + fread( hHrtfStatistics->average_energy_r, sizeof( const float ), lr_iac_len, f_hrtf ); + fread( hHrtfStatistics->inter_aural_coherence, sizeof( const float ), lr_iac_len, f_hrtf ); + } +#else fread( hHrtfStatistics->average_energy_l, sizeof( const float ), lr_iac_len, f_hrtf ); fread( hHrtfStatistics->average_energy_r, sizeof( const float ), lr_iac_len, f_hrtf ); fread( hHrtfStatistics->inter_aural_coherence, sizeof( const float ), lr_iac_len, f_hrtf ); +#endif hHrtfStatistics->fromROM = FALSE; } @@ -579,6 +642,9 @@ static ivas_error TDREND_MIX_LoadHRTF( ivas_hrtfs_header_t hrtf_header; int32_t hrtf_data_size_max; char *hrtf_data; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif header_check_result = IVAS_ERR_OK; @@ -624,7 +690,11 @@ static ivas_error TDREND_MIX_LoadHRTF( for ( hrtf_id = 0; ( hrtf_id < hrtfs_file_header.nb_hrtf ) && ( !is_tdrend ); hrtf_id++ ) { +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( read_hrtf_binary_header( &hrtf_header, &is_fx, f_hrtf ) != IVAS_ERR_OK ) +#else if ( read_hrtf_binary_header( &hrtf_header, f_hrtf ) != IVAS_ERR_OK ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "HRTF binary file not compliant (number of HRTF)" ); } @@ -777,10 +847,13 @@ void destroy_td_hrtf( free( ( *hHrtf )->ModelParamsITD.W_dyn ); free( ( *hHrtf )->ModelParamsITD.azimBsShape_dyn ); free( ( *hHrtf )->ModelParamsITD.elevBsShape_dyn ); + free( ( *hHrtf )->ModelParamsITD.azimBsLen_dyn ); + free( ( *hHrtf )->ModelParamsITD.azimBsStart_dyn ); + free( ( *hHrtf )->ModelParamsITD.elevBsLen_dyn ); + free( ( *hHrtf )->ModelParamsITD.elevBsStart_dyn ); } free( ( *hHrtf )->ModelParams.elevKSeq_dyn ); free( ( *hHrtf )->ModelParams.azim_start_idx_dyn ); - free( ( *hHrtf )->ModelParams.azimDim2_dyn ); free( ( *hHrtf )->ModelParams.azimDim3_dyn ); free( ( *hHrtf )->ModelParams.AlphaL_dyn ); free( ( *hHrtf )->ModelParams.AlphaR_dyn ); @@ -788,6 +861,8 @@ void destroy_td_hrtf( free( ( *hHrtf )->ModelParams.azimShapeIdx_dyn ); free( ( *hHrtf )->ModelParams.azimShapeSampFactor_dyn ); + free( ( *hHrtf )->ModelParams.elevBsLen_dyn ); + free( ( *hHrtf )->ModelParams.elevBsStart_dyn ); free( ( *hHrtf )->ModelParams.elevBsShape_dyn ); for ( i = 0; i < ( *hHrtf )->ModelParams.num_unique_azim_splines; i++ ) @@ -829,7 +904,7 @@ static ivas_error create_HRTF_from_rawdata( { int16_t i, j, k; int16_t max_num_iterations_diffuse; - uint16_t max_total_num_fsamp_per_iteration, max_total_num_fsamp_per_iteration_diff; + uint32_t max_total_num_fsamp_per_iteration, max_total_num_fsamp_per_iteration_diff; uint32_t mem_size; char *hrtf_data_rptr; float *pOut_to_bin_wptr; @@ -944,8 +1019,13 @@ static ivas_error create_HRTF_from_rawdata( } /* max_total_num_fsamp_per_iteration */ +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + max_total_num_fsamp_per_iteration = *( (uint32_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint32_t ); +#else max_total_num_fsamp_per_iteration = *( (uint16_t *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( uint16_t ); +#endif /* coeff_re (the size depends on pIndex_frequency_max) */ for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) @@ -996,8 +1076,13 @@ static ivas_error create_HRTF_from_rawdata( } /* max_total_num_fsamp_per_iteration_diff */ +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + max_total_num_fsamp_per_iteration_diff = *( (uint32_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint32_t ); +#else max_total_num_fsamp_per_iteration_diff = *( (uint16_t *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( uint16_t ); +#endif if ( max_total_num_fsamp_per_iteration_diff != 0 ) { @@ -1047,17 +1132,287 @@ static ivas_error create_HRTF_from_rawdata( return IVAS_ERR_OK; } +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +/*---------------------------------------------------------------------* + * create_HRTF_from_rawdata_fx() + * + * Create HRTF from the raw data (to the HRTF CRend handle) + *---------------------------------------------------------------------*/ -static ivas_error create_fastconv_HRTF_from_rawdata( +static ivas_error create_HRTF_from_rawdata_fx( + HRTFS_HANDLE *hHRTF, /* i/o: HRTF CRend handle */ + char *hrtf_data /* i : pointer to binary file */ +) +{ + int16_t i, j, k; + int16_t max_num_iterations_diffuse; + uint32_t max_total_num_fsamp_per_iteration, max_total_num_fsamp_per_iteration_diff; + uint32_t mem_size, l; + char *hrtf_data_rptr; + float *pOut_to_bin_wptr; + ivas_error error; + Word16 factorQ; + + if ( *hHRTF == NULL ) + { + if ( ( ( *hHRTF ) = (HRTFS_HANDLE) malloc( sizeof( HRTFS_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF binary data\n" ); + } + + if ( ( error = ivas_hrtf_init( *hHRTF ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + return IVAS_ERR_INTERNAL; + } + + ( *hHRTF )->init_from_rom = 0; + hrtf_data_rptr = hrtf_data; + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* latency_s */ + ( *hHRTF )->latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); + + /* max_num_ir */ + ( *hHRTF )->max_num_ir = *( (uint16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint16_t ); + + /* BINAURAL_CHANNELS */ + if ( BINAURAL_CHANNELS != *( (int16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file format not compliant (BINAURAL_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* max_num_iterations */ + ( *hHRTF )->max_num_iterations = *( (int16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( int16_t ); + + /* num_iterations */ + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + ( *hHRTF )->num_iterations[i][j] = *( (uint16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint16_t ); + } + } + + /* pIndex_frequency_max */ + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mem_size = ( *hHRTF )->max_num_iterations * sizeof( uint16_t ); + ( *hHRTF )->pIndex_frequency_max[i][j] = (uint16_t *) malloc( mem_size ); + if ( ( *hHRTF )->pIndex_frequency_max[i][j] == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for pIndex_frequency_max" ); + } + memcpy( ( *hHRTF )->pIndex_frequency_max[i][j], hrtf_data_rptr, mem_size ); + hrtf_data_rptr += mem_size; + } + } + + /* max_num_iterations_diffuse */ + max_num_iterations_diffuse = *( (int16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( int16_t ); + + if ( max_num_iterations_diffuse != 0 ) + { + /* num_iterations_diffuse */ + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + ( *hHRTF )->num_iterations_diffuse[j] = *( (uint16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint16_t ); + } + + /* pIndex_frequency_max_diffuse (the size depends on num_iterations_diffuse) */ + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mem_size = ( *hHRTF )->num_iterations_diffuse[j] * sizeof( uint16_t ); + ( *hHRTF )->pIndex_frequency_max_diffuse[j] = (uint16_t *) malloc( mem_size ); + if ( ( *hHRTF )->pIndex_frequency_max_diffuse[j] == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for pIndex_frequency_max_diffuse" ); + } + memcpy( ( *hHRTF )->pIndex_frequency_max_diffuse[j], hrtf_data_rptr, mem_size ); + hrtf_data_rptr += mem_size; + } + } + + /* index_frequency_max_diffuse */ + ( *hHRTF )->index_frequency_max_diffuse = *( (uint16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint16_t ); + + /* inv_diffuse_weight Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* inv_diffuse_weight */ + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + ( *hHRTF )->inv_diffuse_weight[0][i] = (float) ( *( (Word16 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * factorQ ); + hrtf_data_rptr += sizeof( Word16 ); + } + + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + ( *hHRTF )->inv_diffuse_weight[1][i] = (float) ( *( (Word16 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * factorQ ); + hrtf_data_rptr += sizeof( Word16 ); + } + + /* max_total_num_fsamp_per_iteration */ + max_total_num_fsamp_per_iteration = *( (uint32_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint32_t ); + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* coeff_re (the size depends on pIndex_frequency_max) */ + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mem_size = max_total_num_fsamp_per_iteration * sizeof( float ); + ( *hHRTF )->pOut_to_bin_re[i][j] = (float *) malloc( mem_size ); + if ( ( *hHRTF )->pOut_to_bin_re[i][j] == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for Out_to_bin_re" ); + } + memset( ( *hHRTF )->pOut_to_bin_re[i][j], 0x00, mem_size ); + + pOut_to_bin_wptr = ( *hHRTF )->pOut_to_bin_re[i][j]; + + for ( k = 0; k < ( *hHRTF )->num_iterations[i][j]; k++ ) + { + mem_size = ( *hHRTF )->pIndex_frequency_max[i][j][k] * sizeof( float ); + memcpy( pOut_to_bin_wptr, hrtf_data_rptr, mem_size ); + Word32 *ptW = (Word32 *) pOut_to_bin_wptr; + for ( l = 0; l < ( *hHRTF )->pIndex_frequency_max[i][j][k]; l++ ) + { + pOut_to_bin_wptr[l] = (float) ptW[l] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += mem_size; + pOut_to_bin_wptr += ( *hHRTF )->pIndex_frequency_max[i][j][k]; + } + } + } + + /* coeff_im (the size depends on pIndex_frequency_max) */ + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mem_size = max_total_num_fsamp_per_iteration * sizeof( float ); + ( *hHRTF )->pOut_to_bin_im[i][j] = (float *) malloc( mem_size ); + if ( ( *hHRTF )->pOut_to_bin_im[i][j] == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for Out_to_bin_im" ); + } + memset( ( *hHRTF )->pOut_to_bin_im[i][j], 0x00, mem_size ); + + pOut_to_bin_wptr = ( *hHRTF )->pOut_to_bin_im[i][j]; + for ( k = 0; k < ( *hHRTF )->num_iterations[i][j]; k++ ) + { + mem_size = ( *hHRTF )->pIndex_frequency_max[i][j][k] * sizeof( float ); + memcpy( pOut_to_bin_wptr, hrtf_data_rptr, mem_size ); + Word32 *ptW = (Word32 *) pOut_to_bin_wptr; + for ( l = 0; l < ( *hHRTF )->pIndex_frequency_max[i][j][k]; l++ ) + { + pOut_to_bin_wptr[l] = (float) ptW[l] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += mem_size; + pOut_to_bin_wptr += ( *hHRTF )->pIndex_frequency_max[i][j][k]; + } + } + } + + /* max_total_num_fsamp_per_iteration_diff */ + max_total_num_fsamp_per_iteration_diff = *( (uint32_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint32_t ); + + if ( max_total_num_fsamp_per_iteration_diff != 0 ) + { + // factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + // hrtf_data_rptr += sizeof( Word16 ); + /* coeff_diffuse_re : The size depends on pIndex_frequency_max_diffuse */ + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mem_size = max_total_num_fsamp_per_iteration_diff * sizeof( float ); + ( *hHRTF )->pOut_to_bin_diffuse_re[j] = (float *) malloc( mem_size ); + if ( ( *hHRTF )->pOut_to_bin_diffuse_re[j] == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for pOut_to_bin_diffuse_re" ); + } + memset( ( *hHRTF )->pOut_to_bin_diffuse_re[j], 0x00, mem_size ); + + pOut_to_bin_wptr = ( *hHRTF )->pOut_to_bin_diffuse_re[j]; + + for ( k = 0; k < ( *hHRTF )->num_iterations_diffuse[j]; k++ ) + { + mem_size = ( *hHRTF )->pIndex_frequency_max_diffuse[j][k] * sizeof( float ); + memcpy( pOut_to_bin_wptr, hrtf_data_rptr, mem_size ); + Word32 *ptW = (Word32 *) pOut_to_bin_wptr; + for ( l = 0; l < ( *hHRTF )->pIndex_frequency_max_diffuse[j][k]; l++ ) + { + pOut_to_bin_wptr[l] = (float) ptW[l] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += mem_size; + pOut_to_bin_wptr += ( *hHRTF )->pIndex_frequency_max_diffuse[j][k]; + } + } + + /* coeff_diffuse_im : The size depends on pIndex_frequency_max_diffuse */ + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + mem_size = max_total_num_fsamp_per_iteration_diff * sizeof( float ); + ( *hHRTF )->pOut_to_bin_diffuse_im[j] = (float *) malloc( mem_size ); + if ( ( *hHRTF )->pOut_to_bin_diffuse_im[j] == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for pOut_to_bin_diffuse_im" ); + } + memset( ( *hHRTF )->pOut_to_bin_diffuse_im[j], 0x00, mem_size ); + + pOut_to_bin_wptr = ( *hHRTF )->pOut_to_bin_diffuse_im[j]; + for ( k = 0; k < ( *hHRTF )->num_iterations_diffuse[j]; k++ ) + { + mem_size = ( *hHRTF )->pIndex_frequency_max_diffuse[j][k] * sizeof( float ); + memcpy( pOut_to_bin_wptr, hrtf_data_rptr, mem_size ); + Word32 *ptW = (Word32 *) pOut_to_bin_wptr; + for ( l = 0; l < ( *hHRTF )->pIndex_frequency_max_diffuse[j][k]; l++ ) + { + pOut_to_bin_wptr[l] = (float) ptW[l] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += mem_size; + pOut_to_bin_wptr += ( *hHRTF )->pIndex_frequency_max_diffuse[j][k]; + } + } + } + + return IVAS_ERR_OK; +} + +static ivas_error create_fastconv_HRTF_from_rawdata_fx( HRTFS_FASTCONV_HANDLE *hHRTF, /* i/o: HRTF FastConv handle */ char *hrtf_data, /* i : pointer to binary file */ HRTF_READER_RENDERER_TYPE rend_type, /* i : Renderer type */ BINAURAL_INPUT_AUDIO_CONFIG input_cfg /* i : Input binaural config */ ) { - int16_t i, j; + int16_t i, j, k; char *hrtf_data_rptr; ivas_error error; + Word16 factorQ; + int32_t *ptW32; + int16_t *ptW16; ( *hHRTF )->allocate_init_flag = 0; @@ -1085,8 +1440,13 @@ static ivas_error create_fastconv_HRTF_from_rawdata( /* HRIR */ if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) { - ( *hHRTF )->FASTCONV_HRIR_latency_s = *( (float *) ( hrtf_data_rptr ) ); - hrtf_data_rptr += sizeof( float ); + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* latency_s */ + ( *hHRTF )->FASTCONV_HRIR_latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { @@ -1106,12 +1466,591 @@ static ivas_error create_fastconv_HRTF_from_rawdata( } hrtf_data_rptr += sizeof( uint16_t ); + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS; k++ ) + { + ( *hHRTF )->leftHRIRReal[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS; k++ ) + { + ( *hHRTF )->leftHRIRImag[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS; k++ ) + { + ( *hHRTF )->rightHRIRReal[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS; k++ ) + { + ( *hHRTF )->rightHRIRImag[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( int32_t ); + } + } + } + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) + { + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* latency_s */ + ( *hHRTF )->FASTCONV_HOA3_latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( HOA3_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HOA3_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( BINAURAL_NTAPS_SBA != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_NTAPS_SBA)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->leftHRIRReal_HOA3[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->leftHRIRImag_HOA3[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->rightHRIRReal_HOA3[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->rightHRIRImag_HOA3[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + } + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) + { + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* latency_s */ + ( *hHRTF )->FASTCONV_HOA2_latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( HOA2_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HOA2_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( BINAURAL_NTAPS_SBA != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_NTAPS_SBA)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA2_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->leftHRIRReal_HOA2[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA2_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->leftHRIRImag_HOA2[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA2_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->rightHRIRReal_HOA2[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA2_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->rightHRIRImag_HOA2[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + } + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_FOA ) + { + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* latency_s */ + ( *hHRTF )->FASTCONV_FOA_latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); + + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( FOA_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (FOA_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( BINAURAL_NTAPS_SBA != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_NTAPS_SBA)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->leftHRIRReal_FOA[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->leftHRIRImag_FOA[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->rightHRIRReal_FOA[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_SBA; k++ ) + { + ( *hHRTF )->rightHRIRImag_FOA[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( int32_t ); + } + } + } + /* BRIR */ + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) + { + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + /* latency_s */ + ( *hHRTF )->FASTCONV_BRIR_latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( HRTF_LS_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HRTF_LS_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( BINAURAL_NTAPS_MAX != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_NTAPS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_MAX; k++ ) + { + ( *hHRTF )->leftBRIRReal[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_MAX; k++ ) + { + ( *hHRTF )->leftBRIRImag[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_MAX; k++ ) + { + ( *hHRTF )->rightBRIRReal[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( int32_t ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + ptW32 = (Word32 *) hrtf_data_rptr; + for ( k = 0; k < BINAURAL_NTAPS_MAX; k++ ) + { + ( *hHRTF )->rightBRIRImag[i][j][k] = (float) ptW32[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( int32_t ); + } + } + + /* Reverb Parameters */ + if ( CLDFB_NO_CHANNELS_MAX != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (CLDFB_NO_CHANNELS_MAX)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + ptW16 = (int16_t *) hrtf_data_rptr; + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + ( *hHRTF )->fastconvReverberationTimes[j] = (float) ptW16[j] * powf( 2.f, -1.f * factorQ ); + } + hrtf_data_rptr += CLDFB_NO_CHANNELS_MAX * sizeof( int16_t ); + + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + ptW16 = (int16_t *) hrtf_data_rptr; + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + ( *hHRTF )->fastconvReverberationEneCorrections[j] = (float) ptW16[j] * powf( 2.f, -1.f * factorQ ); + } + hrtf_data_rptr += CLDFB_NO_CHANNELS_MAX * sizeof( int16_t ); + } + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * create_parambin_HRTF_from_rawdata_fx() + * + * + *---------------------------------------------------------------------*/ + +static ivas_error create_parambin_HRTF_from_rawdata_fx( + HRTFS_PARAMBIN_HANDLE *hHRTF, /* i/o: Parametric binauralizer HRTF handle */ + char *hrtf_data /* i : pointer to binary file */ +) +{ + int16_t i, j, k; + char *hrtf_data_rptr; + uint32_t data_size_tmp; + Word16 factorQ; + int16_t *ptW16; + + hrtf_data_rptr = hrtf_data; + + /* HRTF_SH_CHANNELS */ + if ( HRTF_SH_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HRTF_SH_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* HRTF_NUM_BINS */ + if ( HRTF_NUM_BINS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HRTF_NUM_BINS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* HRTF */ + /* Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + data_size_tmp = HRTF_NUM_BINS * sizeof( int16_t ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) + { + ptW16 = (int16_t *) hrtf_data_rptr; + for ( k = 0; k < HRTF_NUM_BINS; k++ ) + { + ( *hHRTF )->hrtfShCoeffsRe[i][j][k] = (float) ptW16[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += data_size_tmp; + } + } + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < HRTF_SH_CHANNELS; j++ ) + { + ptW16 = (int16_t *) hrtf_data_rptr; + for ( k = 0; k < HRTF_NUM_BINS; k++ ) + { + ( *hHRTF )->hrtfShCoeffsIm[i][j][k] = (float) ptW16[k] * powf( 2.f, -1.f * (float) factorQ ); + } + hrtf_data_rptr += data_size_tmp; + } + } + + /* Reverb Parameters */ + if ( CLDFB_NO_CHANNELS_MAX != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (CLDFB_NO_CHANNELS_MAX)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + /* Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + ptW16 = (int16_t *) hrtf_data_rptr; + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + ( *hHRTF )->parametricReverberationTimes[j] = (float) ptW16[j] * powf( 2.f, -1.f * factorQ ); + } + hrtf_data_rptr += CLDFB_NO_CHANNELS_MAX * sizeof( int16_t ); + + /* Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + ptW16 = (int16_t *) hrtf_data_rptr; + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + ( *hHRTF )->parametricReverberationEneCorrections[j] = (float) ptW16[j] * powf( 2.f, -1.f * factorQ ); + } + hrtf_data_rptr += CLDFB_NO_CHANNELS_MAX * sizeof( int16_t ); + + /* Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); + + ptW16 = (int16_t *) hrtf_data_rptr; + for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + ( *hHRTF )->parametricEarlyPartEneCorrection[j] = (float) ptW16[j] * powf( 2.f, -1.f * factorQ ); + } + hrtf_data_rptr += CLDFB_NO_CHANNELS_MAX * sizeof( int16_t ); + + return IVAS_ERR_OK; +} + +#endif + +static ivas_error create_fastconv_HRTF_from_rawdata( + HRTFS_FASTCONV_HANDLE *hHRTF, /* i/o: HRTF FastConv handle */ + char *hrtf_data, /* i : pointer to binary file */ + HRTF_READER_RENDERER_TYPE rend_type, /* i : Renderer type */ + BINAURAL_INPUT_AUDIO_CONFIG input_cfg /* i : Input binaural config */ +) +{ + int16_t i, j; + char *hrtf_data_rptr; + ivas_error error; + + ( *hHRTF )->allocate_init_flag = 0; + + if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV ) + { + if ( ( error = ivas_allocate_binaural_hrtf( *hHRTF, 0, input_cfg, RENDERER_BINAURAL_FASTCONV, ( *hHRTF )->allocate_init_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM ) + { + if ( ( error = ivas_allocate_binaural_hrtf( *hHRTF, 0, input_cfg, RENDERER_BINAURAL_FASTCONV_ROOM, ( *hHRTF )->allocate_init_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "renderer type not compliant" ); + } + + hrtf_data_rptr = hrtf_data; + + /* HRIR */ + if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) + { + ( *hHRTF )->FASTCONV_HRIR_latency_s = *( (float *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( float ); + + if ( BINAURAL_CONVBANDS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_CONVBANDS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( HRTF_LS_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HRTF_LS_CHANNELS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + if ( BINAURAL_NTAPS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (BINAURAL_NTAPS)" ); + } + hrtf_data_rptr += sizeof( uint16_t ); + + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->leftHRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) @@ -1403,6 +2342,9 @@ ivas_error load_fastconv_HRTF_from_binary( ivas_hrtfs_file_header_t hrtfs_file_header; int16_t hrtf_id; int16_t asFastconv = 0; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif f_hrtf = hrtfReader->file; @@ -1429,7 +2371,11 @@ ivas_error load_fastconv_HRTF_from_binary( /* Read & load */ for ( hrtf_id = 0; hrtf_id < hrtfs_file_header.nb_hrtf; hrtf_id++ ) { +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( read_hrtf_binary_header( &hrtf_header, &is_fx, f_hrtf ) != IVAS_ERR_OK ) +#else if ( read_hrtf_binary_header( &hrtf_header, f_hrtf ) != IVAS_ERR_OK ) +#endif { free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "HRTF binary file not compliant (number of HRTF)" ); @@ -1443,13 +2389,26 @@ ivas_error load_fastconv_HRTF_from_binary( return IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "Error in HRTF file reading" ); } - /* Create the HRTF reading the raw data from the binary file */ - if ( ( create_fastconv_HRTF_from_rawdata( &hHrtfFastConv, hrtf_data, hrtf_header.rend_type, hrtf_header.input_cfg ) ) != IVAS_ERR_OK ) +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx ) { - free( hrtf_data ); - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + /* Create the HRTF reading the raw data from the binary file */ + if ( ( create_fastconv_HRTF_from_rawdata_fx( &hHrtfFastConv, hrtf_data, hrtf_header.rend_type, hrtf_header.input_cfg ) ) != IVAS_ERR_OK ) + { + free( hrtf_data ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + } } - + else + { + /* Create the HRTF reading the raw data from the binary file */ + if ( ( create_fastconv_HRTF_from_rawdata( &hHrtfFastConv, hrtf_data, hrtf_header.rend_type, hrtf_header.input_cfg ) ) != IVAS_ERR_OK ) + { + free( hrtf_data ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + } + } +#endif asFastconv = 1; } else @@ -1559,6 +2518,9 @@ ivas_error load_parambin_HRTF_from_binary( ivas_hrtfs_file_header_t hrtfs_file_header; int16_t hrtf_id; int16_t asParam = 0; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif f_hrtf = hrtfReader->file; @@ -1587,13 +2549,20 @@ ivas_error load_parambin_HRTF_from_binary( for ( hrtf_id = 0; hrtf_id < hrtfs_file_header.nb_hrtf; hrtf_id++ ) { +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( read_hrtf_binary_header( &hrtf_header, &is_fx, f_hrtf ) != IVAS_ERR_OK ) +#else if ( read_hrtf_binary_header( &hrtf_header, f_hrtf ) != IVAS_ERR_OK ) +#endif { free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "HRTF binary file not compliant (number of HRTF)" ); } - +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_PARAMETRIC ) /* Parametric binauralizer data is represented as single entity */ +#else if ( hrtf_header.rend_type == HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Parametric binauralizer data is represented as single entity */ +#endif { if ( fread( hrtf_data, 1, hrtf_header.data_size, f_hrtf ) != hrtf_header.data_size ) { @@ -1601,13 +2570,24 @@ ivas_error load_parambin_HRTF_from_binary( return IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "Error in HRTF file reading" ); } - /* Create the HRTF reading the raw data from the binary file */ - if ( ( create_parambin_HRTF_from_rawdata( &hHrtfParamBin, hrtf_data ) ) != IVAS_ERR_OK ) + if ( is_fx == 1 ) { - free( hrtf_data ); - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + /* Create the HRTF reading the raw data from the binary file */ + if ( ( create_parambin_HRTF_from_rawdata_fx( &hHrtfParamBin, hrtf_data ) ) != IVAS_ERR_OK ) + { + free( hrtf_data ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + } + } + else + { + /* Create the HRTF reading the raw data from the binary file */ + if ( ( create_parambin_HRTF_from_rawdata( &hHrtfParamBin, hrtf_data ) ) != IVAS_ERR_OK ) + { + free( hrtf_data ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + } } - asParam = 1; } else @@ -1627,7 +2607,6 @@ ivas_error load_parambin_HRTF_from_binary( } } - /*---------------------------------------------------------------------* * create_SetOfHRTF_from_binary() * @@ -1647,6 +2626,9 @@ ivas_error create_SetOfHRTF_from_binary( ivas_error header_check_result; ivas_hrtfs_file_header_t hrtfs_file_header; int16_t hrtf_id; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif f_hrtf = hrtfReader->file; @@ -1676,7 +2658,11 @@ ivas_error create_SetOfHRTF_from_binary( for ( hrtf_id = 0; hrtf_id < hrtfs_file_header.nb_hrtf; hrtf_id++ ) { +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( read_hrtf_binary_header( &hrtf_header, &is_fx, f_hrtf ) != IVAS_ERR_OK ) +#else if ( read_hrtf_binary_header( &hrtf_header, f_hrtf ) != IVAS_ERR_OK ) +#endif { free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "HRTF binary file not compliant (number of HRTF)" ); @@ -1721,12 +2707,31 @@ ivas_error create_SetOfHRTF_from_binary( if ( hHRTF != NULL ) { - /* Create the HRTF reading the raw data from the binary file */ +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx ) + { + /* Create the HRTF reading the raw data from the binary file */ + if ( ( create_HRTF_from_rawdata_fx( hHRTF, hrtf_data ) ) != IVAS_ERR_OK ) + { + free( hrtf_data ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + } + } + else + { + if ( ( create_HRTF_from_rawdata( hHRTF, hrtf_data ) ) != IVAS_ERR_OK ) + { + free( hrtf_data ); + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); + } + } +#else if ( ( create_HRTF_from_rawdata( hHRTF, hrtf_data ) ) != IVAS_ERR_OK ) { free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); } +#endif } } @@ -1860,7 +2865,7 @@ ivas_error destroy_hrtf_statistics( IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics /* i/o: HRTF statistics handle */ ) { - if ( hHrtfStatistics != NULL && ( *hHrtfStatistics )->fromROM == FALSE ) + if ( ( hHrtfStatistics != NULL ) && ( *hHrtfStatistics != NULL ) && ( ( *hHrtfStatistics )->fromROM == FALSE ) ) { free( ( *hHrtfStatistics )->average_energy_l ); free( ( *hHrtfStatistics )->average_energy_r ); diff --git a/lib_util/hrtf_file_reader.h b/lib_util/hrtf_file_reader.h index ab3254806f681abf6f0cf1dd8fc23644b4630ef1..914489508a5e42365a7af90b75b069d881dc77aa 100644 --- a/lib_util/hrtf_file_reader.h +++ b/lib_util/hrtf_file_reader.h @@ -43,7 +43,9 @@ typedef enum HRTF_READER_RENDERER_BINAURAL_FASTCONV, HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM, HRTF_READER_RENDERER_BINAURAL_PARAMETRIC, +#ifndef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM, +#endif HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD, HRTF_READER_RENDERER_BINAURAL_MIXER_CONV, HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM, diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index decafb0a46dbc19e5de42df5fd09436c54d9eaa9..e07660f4d7314dad740455abbd15b68532557a22 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -124,6 +124,7 @@ struct RenderConfigReader AcousticEnv *pAE; /* Acoustic environments */ uint32_t nDP; /* Number of directivity patterns */ DirectrivityPat *pDP; /* Directivity Pattern */ + float distAtt[3]; /* [MaxDist, RefDist, Rolloff] */ }; @@ -996,6 +997,75 @@ static ivas_error get_bin_outer_attenuation( return IVAS_ERR_OK; } +/*-----------------------------------------------------------------------------------------* + * Function get_bin_max_dist () + * Gets a Maximum Distance value [1.0, 64.0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_max_dist( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant( (int16_t) value, 1.0f, 1.0f ); + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_ref_dist () + * Gets a Reference Distance value [0.1, 6.4] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_ref_dist( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant( (int16_t) value, 0.1f, 0.1f ); + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function get_bin_rolloff () + * Gets a Rollof Factor [0.0, 4.0] + *-----------------------------------------------------------------------------------------*/ + +static ivas_error get_bin_rolloff( + RenderConfigReader *this, /* i/o : Render config reader handle */ + float *pResult /* o : Attenuation value */ +) +{ + ivas_error error; + uint32_t value; + + if ( ( error = read_bin_bits( this, &value, 6 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *pResult = usdequant( (int16_t) value, 0.0f, 0.1f ); + + return IVAS_ERR_OK; +} + /*-----------------------------------------------------------------------------------------* * Function read_txt_vector() @@ -1064,11 +1134,7 @@ static void strip_spaces( while ( pStr[read_idx] ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( !isspace( (int32_t) pStr[read_idx] ) && !iscntrl( (int32_t) pStr[read_idx] ) ) -#else - if ( !isspace( pStr[read_idx] ) && !iscntrl( pStr[read_idx] ) ) -#endif { pStr[write_idx++] = pStr[read_idx]; } @@ -1128,6 +1194,7 @@ ivas_error RenderConfigReader_checkValues( pRoom_acoustics = &hRenderConfig->roomAcoustics; tab_value_err_count = 0; int16_t wall_idx; + int16_t i; /* Verify the number of frequency bands in the config input data */ @@ -1245,6 +1312,20 @@ ivas_error RenderConfigReader_checkValues( pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF; } } + + /* Verify range of distance attenuation parameters: 0.1 <= distAtt[0] <= distAtt[1] */ + /* 0.0 <= distAtt[2] <= 10.0 */ + hRenderConfig->distAtt[0] = max( 0.1f, hRenderConfig->distAtt[0] ); + hRenderConfig->distAtt[1] = max( hRenderConfig->distAtt[0], hRenderConfig->distAtt[1] ); + hRenderConfig->distAtt[2] = max( 0.0f, min( 10.0f, hRenderConfig->distAtt[2] ) ); + + /* Verify range of directivity patterns */ + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + hRenderConfig->directivity[i * 3] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3] ) ); + hRenderConfig->directivity[i * 3 + 1] = max( 0.0f, min( 360.0f, hRenderConfig->directivity[i * 3 + 1] ) ); + hRenderConfig->directivity[i * 3 + 2] = max( 0.0f, min( 1.0f, hRenderConfig->directivity[i * 3 + 2] ) ); + } } @@ -1287,6 +1368,7 @@ ivas_error RenderConfigReader_open( pSelf->pAE = NULL; pSelf->nDP = 0; pSelf->pDP = NULL; + pSelf->distAtt[0] = -1; *ppRenderConfigReader = pSelf; return IVAS_ERR_OK; @@ -1806,6 +1888,34 @@ static ivas_error RenderConfigReader_readBinary( } } } + /**********************************/ + /* Read the distance attenuation */ + /**********************************/ + + /* Has distance attenuation */ + if ( ( error = read_bin_bool( pRenderConfigReader, &value ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( value == true ) + { + /* Read the Max Distance */ + if ( ( error = get_bin_max_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read the Ref Distance */ + if ( ( error = get_bin_ref_dist( pRenderConfigReader, &pRenderConfigReader->distAtt[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Read the Rolloff Facto r*/ + if ( ( error = get_bin_rolloff( pRenderConfigReader, &pRenderConfigReader->distAtt[2] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* Cleanup */ free( pRenderConfigReader->pBitstream ); @@ -1845,10 +1955,8 @@ ivas_error RenderConfigReader_read( uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop; uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr; uint32_t aeHasERsize, aeHasERabs; -#ifdef SPLIT_REND_WITH_HEAD_ROT bool dofProvided = false; bool poseCorrProvided = false; -#endif uint32_t nDP; uint32_t accDPIdx; @@ -2444,7 +2552,6 @@ ivas_error RenderConfigReader_read( free( pValue ); acIdx++; } -#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; @@ -2486,18 +2593,18 @@ ivas_error RenderConfigReader_read( /* 0 DOF implies no pose correction */ if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } } else if ( strcmp( item, "CODEC" ) == 0 ) { if ( strcmp( pValue, "LCLD" ) == 0 ) { - hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD; + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LCLD; } else if ( strcmp( pValue, "LC3PLUS" ) == 0 ) { - hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; } else { @@ -2522,11 +2629,11 @@ ivas_error RenderConfigReader_read( poseCorrProvided = true; if ( strcmp( pValue, "CLDFB" ) == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; } else if ( strcmp( pValue, "NONE" ) == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; /* no pose correction implies 0 DOF */ if ( !dofProvided ) { @@ -2542,25 +2649,32 @@ ivas_error RenderConfigReader_read( { if ( strcmp( pValue, "CREND" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_CREND; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_CREND; } else if ( strcmp( pValue, "FASTCONV" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV; } else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; } else if ( strcmp( pValue, "TDREND" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND; } else { errorHandler( pValue, ERROR_VALUE_INVALID ); } } + else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } #ifdef DEBUGGING else { @@ -2570,7 +2684,6 @@ ivas_error RenderConfigReader_read( } free( pValue ); } -#endif else if ( strcmp( chapter, "DIRECTIVITYSETTING" ) == 0 && strlen( pParams ) != 0 ) { @@ -2653,6 +2766,52 @@ ivas_error RenderConfigReader_read( free( pValue ); accDPIdx++; } + else if ( strcmp( chapter, "DISTANCEATTENUATION" ) == 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + + /* Set default values if parameters are only partially specified */ + pRenderConfigReader->distAtt[0] = 15.75f; + pRenderConfigReader->distAtt[1] = 1.0f; + pRenderConfigReader->distAtt[2] = 1.0f; + + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + + if ( strcmp( item, "MAXDIST" ) == 0 ) + { + /* Read the Maximum distance */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + if ( strcmp( item, "REFDIST" ) == 0 ) + { + /* Read the Reference distance */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[1] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + if ( strcmp( item, "ROLLOFFFACTOR" ) == 0 ) + { + /* Read the Rolloff Factor */ + if ( !sscanf( pValue, "%f", &pRenderConfigReader->distAtt[2] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + } + + free( pValue ); + } + else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; @@ -2821,6 +2980,10 @@ ivas_error RenderConfigReader_getAcousticEnvironment( pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j]; } } + else + { + pAcEnv->use_er = false; + } return IVAS_ERR_OK; } } @@ -2903,6 +3066,32 @@ ivas_error RenderConfigReader_getDirectivity( return IVAS_ERR_OK; } +/*------------------------------------------------------------------------------------------* + * RenderConfigReader_getDistanceAttenuation() + * + * Gets Distance Attenuation + *------------------------------------------------------------------------------------------*/ + +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + float *distAtt /* o : Distance attenuation */ +) +{ + if ( pRenderConfigReader->distAtt[0] == -1 ) + { + distAtt[0] = 15.75f; + distAtt[1] = 1.0f; + distAtt[2] = 1.0f; + } + else + { + distAtt[0] = pRenderConfigReader->distAtt[0]; + distAtt[1] = pRenderConfigReader->distAtt[1]; + distAtt[2] = pRenderConfigReader->distAtt[2]; + } + + return IVAS_ERR_OK; +} /*------------------------------------------------------------------------------------------* * RenderConfigReader_close() diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 445ced79abdb905cc094a5b8d51311d4f3f8f4ba..ef16c818fa3c8320ff3edb75b9f90c39c5e8d540 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -62,6 +62,10 @@ ivas_error RenderConfigReader_getDirectivity( uint16_t *pId, /* i : Directivity pattern ID */ float *directivity /* o : Target directivity */ ); +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + float *distAtt /* o : Distance attenuation */ +); /* Verifies configuration parameters */ ivas_error RenderConfigReader_checkValues( IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* o : Renderer configuration handle */ diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c index 0f16e25984a5742d1519aef46bdb5e68676556ca..69a4ee5e781bc93c953aa1f7b16c6569743c80ef 100644 --- a/lib_util/split_rend_bfi_file_reader.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -32,10 +32,7 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_rend_bfi_file_reader.h" -#include -#include #include #include "prot.h" @@ -100,8 +97,9 @@ ivas_error SplitRendBFIFileReader_open( *-----------------------------------------------------------------------*/ ivas_error SplitRendBFIFileReading( - SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ - int16_t *bfi ) + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi /* o : bad frame indicator */ +) { if ( SplitRendBFIReader->txtfile ? 1 != fscanf( SplitRendBFIReader->bfiFile, "%hd", bfi ) : 1 != fread( bfi, sizeof( *bfi ), 1, SplitRendBFIReader->bfiFile ) ) { @@ -161,4 +159,3 @@ const char *SplitRendBFIFileReader_getFilePath( return SplitRendBFIReader->file_path; } -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_util/split_rend_bfi_file_reader.h b/lib_util/split_rend_bfi_file_reader.h index f0af65254411fcd7c3b0f8f19e3abcc7f82510ea..9fbcbe32ef4a6cd237aa3b481ee65b0e930e093c 100644 --- a/lib_util/split_rend_bfi_file_reader.h +++ b/lib_util/split_rend_bfi_file_reader.h @@ -34,7 +34,6 @@ #define IVAS_SR_BFI_FILE_READER_H #include "common_api_types.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT typedef struct SplitRendBFIFileReader SplitRendBFIFileReader; @@ -45,7 +44,8 @@ ivas_error SplitRendBFIFileReader_open( ivas_error SplitRendBFIFileReading( SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ - int16_t *bfi ); + int16_t *bfi /* o : bad frame indicator */ +); void SplitRendBFIFileReader_close( SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ @@ -56,5 +56,4 @@ const char *SplitRendBFIFileReader_getFilePath( ); -#endif /* SPLIT_REND_WITH_HEAD_ROT */ #endif /* IVAS_SR_BFI_FILE_READER_H */ diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index d1a85776bd61eaf1aa9cda995c4a312d98aebc1e..ca5637c8d73114534f8034d0659ec98128f48049 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -31,16 +31,9 @@ *******************************************************************************************************/ #include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_render_file_read_write.h" -#include #include -#include -#include -#include "cmdl_tools.h" #include "prot.h" -#include "ivas_cnst.h" /*------------------------------------------------------------------------------------------* @@ -68,7 +61,13 @@ struct SplitFileReadWrite ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, - char *filename ) + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms, + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres ) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -104,6 +103,42 @@ ivas_error split_rend_reader_open( fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file ); + /* read codec signalling */ + if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read pose correction signalling */ + if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read transport codec frame size signalling */ + if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read ISAR bitstream frame size signalling */ + if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read sampling rate signalling */ + if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read LC3plus highres signalling */ + if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; return IVAS_ERR_OK; @@ -120,7 +155,13 @@ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, const int16_t delayNumSamples, - const int32_t delayTimeScale ) + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + const int16_t codec_frame_size_ms, + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres ) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -155,6 +196,42 @@ ivas_error split_rend_writer_open( hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale ); fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ); + /* Write codec signalling */ + if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write pose correction signalling */ + if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write transport codec frame size signalling */ + if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write ISAR bit stream frame size signalling */ + if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write sampling rate signalling */ + if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write LC3plus highres signalling */ + if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; return IVAS_ERR_OK; @@ -167,7 +244,7 @@ ivas_error split_rend_writer_open( * *-----------------------------------------------------------------------------------------*/ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ) { if ( ( *hhSplitRendFileReadWrite ) != NULL ) @@ -182,7 +259,7 @@ ivas_error split_rend_reader_writer_close( *hhSplitRendFileReadWrite = NULL; } - return IVAS_ERR_OK; + return; } @@ -196,10 +273,7 @@ ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ) + int32_t *bits_written ) { char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; size_t header_len, i, num_bytes; @@ -232,23 +306,6 @@ ivas_error split_rend_write_bitstream_to_file( return IVAS_ERR_FAILED_FILE_WRITE; } - /* Write codec signalling */ - if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - - /* Write pose correction signalling */ - if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - /* Write frame size signalling */ - if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - /* write num bytes */ if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -278,10 +335,7 @@ ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC *codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ) + int32_t *bits_written ) { char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; @@ -326,23 +380,6 @@ ivas_error split_rend_read_bits_from_file( return IVAS_ERR_FAILED_FILE_READ; } - /* read codec signalling */ - if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - - /* read pose correction signalling */ - if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - /* read frame size signalling */ - if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - /* write num bytes */ if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -354,7 +391,7 @@ ivas_error split_rend_read_bits_from_file( { return IVAS_ERR_FAILED_FILE_READ; } - for ( i = 0; i < IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) + for ( i = 0; i < ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) { bits[num_bytes + i] = 0; } @@ -385,4 +422,3 @@ ivas_error split_rend_read_pre_rend_delay_ns( return IVAS_ERR_OK; } -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index e933fe3df3a2f5f955a9c62f19c8c773f8efcdf5..6d9bc7e839a512ad0c10cce739b05df6931e4762 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -34,25 +34,35 @@ #define SPLIT_RENDER_FILE_READ_WRITE_H #include "common_api_types.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT typedef struct SplitFileReadWrite SplitFileReadWrite; -/* Allocates and initializes a a split renderer reader instance */ +/* Allocates and initializes a a split renderer reader instance */ ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, - char *filename ); - - -/* Allocates and initializes a a split renderer writer instance */ + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms, + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres ); + +/* Allocates and initializes a a split renderer writer instance */ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, const int16_t delayNumSamples, - const int32_t delayTimeScale ); - -/* Closes the split renderer reader/writer and deallocates memory */ -ivas_error split_rend_reader_writer_close( + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + const int16_t codec_frame_size_ms, + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres ); + +/* Closes the split renderer reader/writer and deallocates memory */ +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ); /*write split rend coded bitstream to file */ @@ -60,25 +70,18 @@ ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ); + int32_t *bits_written ); /* read split rend coded bits from file */ ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC *codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ); + int32_t *bits_written ); /* read split pre rend delay */ ivas_error split_rend_read_pre_rend_delay_ns( SplitFileReadWrite *hSplitRendFileReadWrite, uint32_t *delay_ns ); -#endif /* SPLIT_REND_WITH_HEAD_ROT */ #endif /* SPLIT_RENDER_FILE_READ_WRITE_H */ diff --git a/readme.txt b/readme.txt index 0cdb7ddaaffc85e4671f3045977469446332e8f2..a50bc83c1ef8d06ad0d381664239c2fec058b2dd 100644 --- a/readme.txt +++ b/readme.txt @@ -33,11 +33,12 @@ These files represent the 3GPP EVS Codec Extension for Immersive Voice and Audio Services (IVAS) floating-point C simulation. All code is writtten -in ISO/IEC C99. The system is implemented as three separate programs: +in ISO/IEC C99. The system is implemented as four separate programs: - IVAS_cod Encoder - IVAS_dec Decoder - IVAS_rend Renderer + IVAS_cod IVAS Encoder + IVAS_dec IVAS Decoder + IVAS_rend IVAS External Renderer + ISAR_post_rend ISAR Post Renderer For encoding using the coder program, the input is a binary audio file (*.8k, *.16k, *.32k, *.48k) and the output is a binary @@ -128,23 +129,25 @@ should have the following structure: |-- lib_debug |-- lib_dec |-- lib_enc - |-- lib_rend + |-- lib_isar + |-- lib_lc3plus + |-- lib_rend |-- lib_util |-- readme.txt |-- .clang-format The package includes a Makefile for gcc, which has been verified on 32-bit Linux systems. The code can be compiled by entering the directory -"c-code" and typing the command: make. The resulting encoder/decoder/renderer -executables are named "IVAS_cod", "IVAS_dec", and "IVAS_rend". All reside -in the c-code directory. +"c-code" and typing the command: make. The resulting encoder/decoder/renderer/ +ISAR_post_renderer executables are named "IVAS_cod", "IVAS_dec", "IVAS_rend", +and "ISAR_post_rend". All reside in the c-code directory. The package also includes a solution-file for Microsoft Visual Studio 2017 (x86). To compile the code, please open "Workspace_msvc\Workspace_msvc.sln" and build "encoder" for the encoder, "decoder" for the decoder, and "renderer" for the -renderer executable. The resulting encoder/decoder/renderer executables are -"IVAS_cod.exe", "IVAS_dec.exe", and "IVAS_rend.exe". All reside in the c-code -main directory. +renderer executable. The resulting encoder/decoder/renderer/ISAR_post_renderer +executables are "IVAS_cod.exe", "IVAS_dec.exe", "IVAS_rend.exe", and +"ISAR_post_rend.exe". All reside in the c-code main directory. RUNNING THE SOFTWARE @@ -241,7 +244,8 @@ Usage for IVAS: IVAS_dec.exe [Options] OutputConf Fs bitstream_file output_file Mandatory parameters: --------------------- OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA, - HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT + HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, + BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT By default, channel order and loudspeaker positions are equal to the encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker layout file. See below for details. @@ -286,8 +290,11 @@ Options: -exof File : External orientation trajectory File for simulation of external orientations -dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be specified) for binaural output configuration --aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. +-aeid ID | File : Acoustic environment ID (number > 0) or + alternatively, it can be a text file where each line contains "ID duration" + for BINAURAL_ROOM_REVERB output configuration. -level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. +-om File : Coded metadata File for BINAURAL_SPLIT_PCM OutputConf Currently, all values default to level 3 (full functionality). -q : Quiet mode, limit printouts to terminal, default is deactivated @@ -318,7 +325,9 @@ Options: -exof File : External orientation trajectory File for simulation of external orientations -dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be specified) for binaural output configuration --aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. +-aeid ID | File : Acoustic environment ID (number > 0) + alternatively, it can be a text file where each line contains "ID duration" + for BINAURAL_ROOM_REVERB output configuration. -lp Position : Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees. If specified, overrides the default behavior which attempts to map input to output LFE channel(s) @@ -329,11 +338,27 @@ Options: -g : Input gain (linear, not in dB) to be applied to input audio file -l : List supported audio formats -smd : Metadata Synchronization Delay in ms, Default is 0. Quantized by 5ms subframes. +-om File : Coded metadata File for BINAURAL_SPLIT_PCM output format -level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. Currently, all values default to level 3 (full functionality). -q : Quiet mode, limit printouts to terminal, default is deactivated +The usage of the "ISAR_post_rend" program: +------------------------------------------ + +Usage: ISAR_post_rend [options] + +Options: +-------- +-i File : Input File (input file is bitstream if format is BINAURAL_SPLIT_CODED, or PCM/WAV file if format is BINAURAL_SPLIT_PCM) +-if Format : Input Format of input (BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM) +-im File : Coded metadata File for BINAURAL_SPLIT_PCM input format +-o File : Output Audio File in BINAURAL format +-fs : Input sampling rate in kHz (48) +-prbfi File : BFI File + + MULTICHANNEL LOUDSPEAKER INPUT / OUTPUT CONFIGURATIONS ====================================================== The loudspeaker positions for each MC layouts are assumed to have the following azimuth and elevation diff --git a/readme_split_rendering.txt b/readme_split_rendering.txt deleted file mode 100644 index 60db2cc5a6f7e184af5657b33465d60469f2b474..0000000000000000000000000000000000000000 --- a/readme_split_rendering.txt +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -For the IVAS Readme.txt, please refer to Readme.txt. - -This readme_split_rendering.txt describes a usage of the binaural split -rendering feature in the IVAS codec. This feature is implemented as part of -the following two separate programs: - - IVAS_dec Decoder - IVAS_rend Renderer - - - - INSTALLING THE SOFTWARE - ======================= - -Same as described in Readme.txt while the structure looks as follows: - -. -`-- c-code - |-- Makefile - |-- Workspace_msvc - |-- apps - |-- lib_com - |-- lib_debug - |-- lib_dec - |-- lib_enc - |-- lib_lc3plus - |-- lib_rend - |-- lib_util - |-- readme.txt - |-- readme_split_rendering.txt - - - - RUNNING THE SOFTWARE - ==================== - -The usage of the "IVAS_cod" program: ------------------------------------- - -Same as described in Readme.txt. - - - -The usage of the "IVAS_dec" program: ------------------------------------- - -Same as described in Readme.txt while more command-line options are avilable. - -Usage for IVAS: IVAS_dec.exe [Options] OutputConf Fs bitstream_file output_file - -Additional options: -------------------- -OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA, - HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, - BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT --om File : Coded metadata File for BINAURAL_SPLIT_PCM output mode - - - -The usage of the "IVAS_rend" program: -------------------------------------- - -Same as described in Readme.txt while more command-line options are avilable. - -Usage: IVAS_rend [options] - -Additional options: -------------------- --om File : Coded metadata File for BINAURAL_SPLIT_PCM output mode --im File : Coded metadata File for BINAURAL_SPLIT_PCM input mode --prbfi File : Split rendering option: bfi File - - - - - RUNNING THE SELF TEST - ===================== - -Same as described in Readme.txt except of the renderer configuration text file which -can additionally be used to configure the pre-rendering step of the split binaural -renderer. All split renderer parameters are optional. - -The detailed syntax of the renderer configuration text can be found in 3GPP TS 26.258. diff --git a/scripts/binauralRenderer_interface/CMakeLists.txt b/scripts/binauralRenderer_interface/CMakeLists.txt index e51ab3b2145184c81f21c16f5db546fde6d19975..54b670e89985afbbdc0b4d0be5d6d3d261193a58 100644 --- a/scripts/binauralRenderer_interface/CMakeLists.txt +++ b/scripts/binauralRenderer_interface/CMakeLists.txt @@ -9,9 +9,11 @@ set(IVAS_TRUNK_DEC_PATH ${IVAS_TRUNK_PATH}/lib_dec) set(IVAS_TRUNK_REND_PATH ${IVAS_TRUNK_PATH}/lib_rend) set(IVAS_TRUNK_ENC_PATH ${IVAS_TRUNK_PATH}/lib_enc) set(IVAS_TRUNK_COM_PATH ${IVAS_TRUNK_PATH}/lib_com) +set(IVAS_TRUNK_ISAR_PATH ${IVAS_TRUNK_PATH}/lib_isar) +set(IVAS_TRUNK_LC3_PATH ${IVAS_TRUNK_PATH}/lib_lc3plus) set(IVAS_TRUNK_DEBUG_PATH ${IVAS_TRUNK_PATH}/lib_debug) -option(USE_MATLAB_ENG "Use matlab engine" OFF) # allows to use sofa file as input to the exe, but on windows requires to register matlab as a com server type in matlab "comserver('register')"" +option(USE_MATLAB_ENG "Use matlab engine" OFF) # allows to use sofa file as input to the exe, but on windows requires to register matlab as a com server type in matlab "comserver('register')"" find_package(Matlab REQUIRED) message("Matlab_VERSION = ${Matlab_VERSION}") message("Matlab_ROOT_DIR = ${Matlab_ROOT_DIR}") @@ -27,7 +29,8 @@ message("Matlab_MX_LIBRARY = ${Matlab_MX_LIBRARY}") message("Matlab_MEX_LIBRARY = ${Matlab_MEX_LIBRARY}") message("Matlab_ENGINE_LIBRARY = ${Matlab_ENGINE_LIBRARY}") message("Matlab_DATAARRAY_LIBRARY = ${Matlab_DATAARRAY_LIBRARY}") -include_directories(${Matlab_INCLUDE_DIRS} ${IVAS_TRUNK_UTIL_PATH} ${IVAS_TRUNK_ENC_PATH} ${IVAS_TRUNK_DEC_PATH} ${IVAS_TRUNK_REND_PATH} ${IVAS_TRUNK_COM_PATH} ${IVAS_TRUNK_DEBUG_PATH}) +include_directories(${Matlab_INCLUDE_DIRS} ${IVAS_TRUNK_UTIL_PATH} ${IVAS_TRUNK_ENC_PATH} ${IVAS_TRUNK_DEC_PATH} ${IVAS_TRUNK_REND_PATH} ${IVAS_TRUNK_COM_PATH} ${IVAS_TRUNK_ISAR_PATH} ${IVAS_TRUNK_LC3_PATH} ${IVAS_TRUNK_DEBUG_PATH}) + if(USE_MATLAB_ENG) string(REPLACE "mex" "eng" Matlab_ENG_LIBRARY ${Matlab_MEX_LIBRARY}) add_definitions(-DUSE_MATLAB_ENG) @@ -71,9 +74,11 @@ add_library(${PROJECT_NAME}_lib STATIC ${SOURCE_FILES_C} ${SOURCE_FILES_H}) add_executable(${PROJECT_NAME} generate_crend_ivas_tables_from_sofa.c) target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib ${Matlab_MAT_LIBRARY} ${Matlab_MX_LIBRARY}) + if(UNIX AND NOT APPLE) target_link_libraries(${PROJECT_NAME} libstdc++.so.6 -lm -ldl) endif() + if(USE_MATLAB_ENG) target_link_libraries(${PROJECT_NAME} ${Matlab_ENG_LIBRARY}) endif() diff --git a/scripts/binauralRenderer_interface/Table_Format_Converter/CMakeLists.txt b/scripts/binauralRenderer_interface/Table_Format_Converter/CMakeLists.txt index 3bd7ec1f4b078a631d9f4bd5e7b3b2d91e02ba4f..6692b4de21d119b118b8b9f5eea644f9db6f4851 100644 --- a/scripts/binauralRenderer_interface/Table_Format_Converter/CMakeLists.txt +++ b/scripts/binauralRenderer_interface/Table_Format_Converter/CMakeLists.txt @@ -19,9 +19,10 @@ set(IVAS_ENC_PATH ${IVAS_PATH}/lib_enc) set(IVAS_COM_PATH ${IVAS_PATH}/lib_com) set(IVAS_REND_PATH ${IVAS_PATH}/lib_rend) set(IVAS_DEBUG_PATH ${IVAS_PATH}/lib_debug) -set(IVAS_LC3PLUS_PATH ${IVAS_PATH}/lc3plus) +set(IVAS_LC3PLUS_PATH ${IVAS_PATH}/lib_lc3plus) +set(IVAS_ISAR_PATH ${IVAS_PATH}/lib_isar) -include_directories(${IVAS_UTIL_PATH} ${IVAS_ENC_PATH} ${IVAS_DEC_PATH} ${IVAS_COM_PATH} ${IVAS_REND_PATH} ${IVAS_DEBUG_PATH} ${IVAS_LC3PLUS_PATH}) +include_directories(${IVAS_UTIL_PATH} ${IVAS_ENC_PATH} ${IVAS_DEC_PATH} ${IVAS_COM_PATH} ${IVAS_REND_PATH} ${IVAS_DEBUG_PATH} ${IVAS_LC3PLUS_PATH} ${IVAS_ISAR_PATH}) set(SOURCE_FILES_C ${IVAS_REND_PATH}/ivas_rom_binauralRenderer.c @@ -40,4 +41,3 @@ add_executable(${PROJECT_NAME} generate_tables_from_rom_to_bin.c) target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib) add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") - diff --git a/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c b/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c index 7e0d07685a8f6ed28b9483ae1172ab90b537d7af..eacfeaa06b8e10ee4cf4c644fc38fe806c823e14 100644 --- a/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c +++ b/scripts/binauralRenderer_interface/Table_Format_Converter/generate_tables_from_rom_to_bin.c @@ -40,6 +40,9 @@ #include "ivas_stat_dec.h" #include "hrtf_file_reader.h" #include "ivas_rom_rend.h" +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +#include +#endif #define FILE_HEADER @@ -57,9 +60,13 @@ #define DEFAULT_BIN_FILE_EXT ".bin" +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +#define DEFAULT_BIN_FILE_FX_FLAG 0x1000 +#endif + #define IVAS_NB_RENDERER_TYPE 7 -#define IVAS_NB_AUDIO_CONFIG 4 -#define IVAS_NB_SAMPLERATE 3 +#define IVAS_NB_AUDIO_CONFIG 4 +#define IVAS_NB_SAMPLERATE 3 const HRTF_READER_RENDERER_TYPE rend_types[IVAS_NB_RENDERER_TYPE] = { @@ -95,8 +102,13 @@ typedef struct _crend_hrtf_tables_dimensions int16_t max_num_ir; int16_t max_num_iterations; int16_t max_num_iterations_diffuse; +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + uint32_t max_total_num_fsamp_per_iteration; + uint32_t max_total_num_fsamp_per_iteration_diff; +#else uint16_t max_total_num_fsamp_per_iteration; uint16_t max_total_num_fsamp_per_iteration_diff; +#endif } crend_hrtf_tables_dimensions; @@ -138,7 +150,9 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD int16_t get_crend_hrtf_tables( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUDIO_CONFIG input_cfg, int32_t frequency, crend_hrtf_tables_pointers *hrtf_table_ptrs /*OUT*/, crend_hrtf_tables_dimensions *hrtf_table_dims /*OUT*/ ); int32_t compute_crend_hrtf_data_size( crend_hrtf_tables_pointers *hrtf_table_ptrs, crend_hrtf_tables_dimensions *hrtf_table_dims ); - +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +int32_t compute_crend_hrtf_data_size_fx( crend_hrtf_tables_pointers *hrtf_table_ptrs, crend_hrtf_tables_dimensions *hrtf_table_dims ); +#endif /*---------------------------------------------------------------------* * usage_gen_crend_tables() * @@ -169,10 +183,10 @@ void usage_tables_format_converter( void ) fprintf( stdout, "-input_fastconv_file_name : if exist name of input fastconv file with extension.\n" ); fprintf( stdout, "-input_param_file_path : if exist path of binary file for parametric renderer.\n" ); fprintf( stdout, "-input_param_file_name : if exist name of input param file with extension.\n" ); - fprintf( stdout, "-input_mixerconv_file_hrir_path : if exist path of binary files for mixer_conv hrir renderer.\n" ); - fprintf( stdout, "-input_mixerconv_file_hrir_name : if exist common name of input mixer_conv hrir files.\n" ); - fprintf( stdout, "-input_mixerconv_file_brir_path : if exist path of binary files for mixer_conv brir renderer.\n" ); - fprintf( stdout, "-input_mixerconv_file_brir_name : if exist common name of input mixer_conv brir files.\n" ); + fprintf( stdout, "-input_mixerconv_hrir_file_path : if exist path of binary files for mixer_conv hrir renderer.\n" ); + fprintf( stdout, "-input_mixerconv_hrir_file_name : if exist common name of input mixer_conv hrir files.\n" ); + fprintf( stdout, "-input_mixerconv_brir_file_path : if exist path of binary files for mixer_conv brir renderer.\n" ); + fprintf( stdout, "-input_mixerconv_brir_file_name : if exist common name of input mixer_conv brir files.\n" ); fprintf( stdout, "\n" ); fprintf( stdout, "For example :\n" #ifdef _WIN32 @@ -613,7 +627,9 @@ char *create_hrtf_crend( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD { int32_t mixerconv_hrtf_header_size, mixerconv_hrtf_data_size; char *mixerconv_hrtf = NULL, *mixerconv_hrtf_wptr; - +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif char *full_in_mixerconv_path = NULL; FILE *input_mixerconv_bin_file = NULL; @@ -641,11 +657,35 @@ char *create_hrtf_crend( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD { configuration_name = "HOA3_HRIR"; } +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( strstr( input_mixerconv_bin_hrir_file_name, "_fx" ) ) + { + input_mixerconv_bin_hrir_file_name[strlen( input_mixerconv_bin_hrir_file_name ) - 3] = '\0'; + is_fx = 1; + } + full_in_mixerconv_path = malloc( strlen( input_mixerconv_bin_hrir_path ) + 1 + strlen( input_mixerconv_bin_hrir_file_name ) + 1 + strlen( configuration_name ) + 1 + 5 + strlen( DEFAULT_BIN_FILE_EXT ) + 1 + ( is_fx == 1 ? 3 : 0 ) ); +#ifdef _WIN32 + if ( is_fx == 1 ) + sprintf( full_in_mixerconv_path, "%s\\%s_%s_%dkHz_fx%s", input_mixerconv_bin_hrir_path, input_mixerconv_bin_hrir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); + else + sprintf( full_in_mixerconv_path, "%s\\%s_%s_%dkHz%s", input_mixerconv_bin_hrir_path, input_mixerconv_bin_hrir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#else + if ( is_fx == 1 ) + sprintf( full_in_mixerconv_path, "%s/%s_%s_%dkHz_fx%s", input_mixerconv_bin_hrir_path, input_mixerconv_bin_hrir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); + else + sprintf( full_in_mixerconv_path, "%s/%s_%s_%dkHz%s", input_mixerconv_bin_hrir_path, input_mixerconv_bin_hrir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#endif + if ( is_fx == 1 ) + { + input_mixerconv_bin_hrir_file_name[strlen( input_mixerconv_bin_hrir_file_name )] = '_'; + } +#else full_in_mixerconv_path = malloc( strlen( input_mixerconv_bin_hrir_path ) + 1 + strlen( input_mixerconv_bin_hrir_file_name ) + 1 + strlen( configuration_name ) + 1 + 5 + strlen( DEFAULT_BIN_FILE_EXT ) + 1 ); #ifdef _WIN32 sprintf( full_in_mixerconv_path, "%s\\%s_%s_%dkHz%s", input_mixerconv_bin_hrir_path, input_mixerconv_bin_hrir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); #else sprintf( full_in_mixerconv_path, "%s/%s_%s_%dkHz%s", input_mixerconv_bin_hrir_path, input_mixerconv_bin_hrir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#endif #endif } else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM ) @@ -666,11 +706,35 @@ char *create_hrtf_crend( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD { return NULL; } +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( strstr( input_mixerconv_bin_brir_file_name, "_fx" ) ) + { + input_mixerconv_bin_brir_file_name[strlen( input_mixerconv_bin_brir_file_name ) - 3] = '\0'; + is_fx = 1; + } + full_in_mixerconv_path = malloc( strlen( input_mixerconv_bin_brir_path ) + 1 + strlen( input_mixerconv_bin_brir_file_name ) + 1 + strlen( configuration_name ) + 1 + 5 + strlen( DEFAULT_BIN_FILE_EXT ) + 1 ); +#ifdef _WIN32 + if ( is_fx == 1 ) + sprintf( full_in_mixerconv_path, "%s\\%s_%s_%dkHz_fx%s", input_mixerconv_bin_brir_path, input_mixerconv_bin_brir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); + else + sprintf( full_in_mixerconv_path, "%s\\%s_%s_%dkHz%s", input_mixerconv_bin_brir_path, input_mixerconv_bin_brir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#else + if ( is_fx == 1 ) + sprintf( full_in_mixerconv_path, "%s/%s_%s_%dkHz_fx%s", input_mixerconv_bin_brir_path, input_mixerconv_bin_brir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); + else + sprintf( full_in_mixerconv_path, "%s/%s_%s_%dkHz%s", input_mixerconv_bin_brir_path, input_mixerconv_bin_brir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#endif + if ( is_fx == 1 ) + { + input_mixerconv_bin_brir_file_name[strlen( input_mixerconv_bin_brir_file_name )] = '_'; + } +#else full_in_mixerconv_path = malloc( strlen( input_mixerconv_bin_brir_path ) + 1 + strlen( input_mixerconv_bin_brir_file_name ) + 1 + strlen( configuration_name ) + 1 + 5 + strlen( DEFAULT_BIN_FILE_EXT ) + 1 ); #ifdef _WIN32 sprintf( full_in_mixerconv_path, "%s\\%s_%s_%dkHz%s", input_mixerconv_bin_brir_path, input_mixerconv_bin_brir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); #else sprintf( full_in_mixerconv_path, "%s/%s_%s_%dkHz%s", input_mixerconv_bin_brir_path, input_mixerconv_bin_brir_file_name, configuration_name, frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#endif #endif } @@ -706,6 +770,12 @@ char *create_hrtf_crend( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD // Get the HRTF header // Renderer type +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx == 1 ) + { + rend_type = rend_type + DEFAULT_BIN_FILE_FX_FLAG; + } +#endif memcpy( mixerconv_hrtf_wptr, &( rend_type ), sizeof( int32_t ) ); mixerconv_hrtf_wptr += sizeof( int32_t ); @@ -722,8 +792,7 @@ char *create_hrtf_crend( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD mixerconv_hrtf_wptr += sizeof( uint32_t ); // Get the HRTF raw data - - if ( fread( mixerconv_hrtf_wptr, mixerconv_hrtf_data_size, 1, input_mixerconv_bin_file ) != 1 ) + if ( fread( mixerconv_hrtf_wptr, 1, mixerconv_hrtf_data_size, input_mixerconv_bin_file ) != mixerconv_hrtf_data_size ) { fprintf( stderr, "Reading of the mixer_conv hrtf failed!\n\n" ); fclose( input_mixerconv_bin_file ); @@ -866,9 +935,40 @@ char *create_reverb( int32_t frequency, int32_t *hrtf_size ) FILE *input_reverb_file = NULL; int32_t reverb_header_size, reverb_data_size; char *reverb = NULL, *reverb_wptr, *full_in_reverb_path = NULL; - +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif *hrtf_size = 0; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( strstr( input_reverb_file_name, "_fx" ) ) + { + input_reverb_file_name[strlen( input_reverb_file_name ) - 3] = '\0'; + is_fx = 1; + } + full_in_reverb_path = (char *) malloc( sizeof( char ) * ( strlen( input_reverb_file_path ) + 1 + strlen( input_reverb_file_name ) + 1 + strlen( "Reverb" ) + 1 + 5 + strlen( DEFAULT_BIN_FILE_EXT ) + 1 ) + ( is_fx == 1 ? 3 : 0 ) ); + if ( full_in_reverb_path == NULL ) + { + fprintf( stderr, "Memory issue for full input td path!\n\n" ); + rom2bin_terminat(); + return NULL; + } +#ifdef _WIN32 + if ( is_fx == 1 ) + sprintf( full_in_reverb_path, "%s\\%s_%s_%dkHz_fx%s", input_reverb_file_path, input_reverb_file_name, "Reverb", frequency / 1000, DEFAULT_BIN_FILE_EXT ); + else + sprintf( full_in_reverb_path, "%s\\%s_%s_%dkHz%s", input_reverb_file_path, input_reverb_file_name, "Reverb", frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#else + if ( is_fx == 1 ) + sprintf( full_in_reverb_path, "%s/%s_%s_%dkHz_fx%s", input_reverb_file_path, input_reverb_file_name, "Reverb", frequency / 1000, DEFAULT_BIN_FILE_EXT ); + else + sprintf( full_in_reverb_path, "%s/%s_%s_%dkHz%s", input_reverb_file_path, input_reverb_file_name, "Reverb", frequency / 1000, DEFAULT_BIN_FILE_EXT ); +#endif + if ( is_fx == 1 ) + { + input_reverb_file_name[strlen( input_reverb_file_name )] = '_'; + } +#else full_in_reverb_path = (char *) malloc( sizeof( char ) * ( strlen( input_reverb_file_path ) + 1 + strlen( input_reverb_file_name ) + 1 + strlen( "Reverb" ) + 1 + 5 + strlen( DEFAULT_BIN_FILE_EXT ) + 1 ) ); if ( full_in_reverb_path == NULL ) { @@ -882,6 +982,9 @@ char *create_reverb( int32_t frequency, int32_t *hrtf_size ) #else sprintf( full_in_reverb_path, "%s/%s_%s_%dkHz%s", input_reverb_file_path, input_reverb_file_name, "Reverb", frequency / 1000, DEFAULT_BIN_FILE_EXT ); #endif + +#endif + input_reverb_file = fopen( full_in_reverb_path, "rb" ); if ( input_reverb_file != NULL ) @@ -917,7 +1020,18 @@ char *create_reverb( int32_t frequency, int32_t *hrtf_size ) // Get the HRTF header // Renderer type +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx == 1 ) + { + *( (int32_t *) ( reverb_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_REVERB_ALL + DEFAULT_BIN_FILE_FX_FLAG; + } + else + { + *( (int32_t *) ( reverb_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_REVERB_ALL; + } +#else *( (int32_t *) ( reverb_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_REVERB_ALL; +#endif reverb_wptr += sizeof( int32_t ); // Decoder output format @@ -974,6 +1088,9 @@ char *create_hrtf_fastconv( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_ int32_t hrtf_total_file_size = 0, hrtf_data_size = 0; int16_t nbHrft = 0, ind; ivas_hrtfs_header_t hrtf_header; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + int16_t is_fx = 0; +#endif fastconv_hrtf_data_size = 0; @@ -1024,8 +1141,14 @@ char *create_hrtf_fastconv( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_ return NULL; } - // Get the HRTF raw data + // Get the HRTF raw data +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( strstr( input_fastconv_bin_file_name, "_fx" ) ) + { + is_fx = 1; + } +#endif full_in_fastconv_path = (char *) malloc( sizeof( char ) * ( strlen( input_fastconv_bin_path ) + strlen( input_fastconv_bin_file_name ) + 2 ) ); if ( full_in_fastconv_path == NULL ) { @@ -1158,6 +1281,12 @@ char *create_hrtf_fastconv( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_ // Get the HRTF header // Renderer type +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx == 1 ) + { + rend_type = rend_type + DEFAULT_BIN_FILE_FX_FLAG; + } +#endif memcpy( fastconv_hrtf_wptr, &( rend_type ), sizeof( int32_t ) ); fastconv_hrtf_wptr += sizeof( int32_t ); @@ -1175,7 +1304,7 @@ char *create_hrtf_fastconv( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_ // Get the HRTF raw data - if ( fread( fastconv_hrtf_wptr, fastconv_hrtf_data_size, 1, input_fastconv_bin_file ) != 1 ) + if ( fread( fastconv_hrtf_wptr, 1, fastconv_hrtf_data_size, input_fastconv_bin_file ) != fastconv_hrtf_data_size ) { fprintf( stderr, "Reading of the fastconv hrtf failed!\n\n" ); fclose( input_fastconv_bin_file ); @@ -1210,6 +1339,16 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) uint32_t data_size_tmp; int16_t i, j; + FILE *input_param_bin_file = NULL; + +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + char hrtf_identifier[8] = ""; + int16_t is_fx = 0; + if ( strstr( input_param_bin_file_name, "_fx" ) ) + { + is_fx = 1; + } +#else uint8_t file_read_ok; float hrtfShCoeffsReFile[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; @@ -1218,8 +1357,7 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) float parametricReverberationTimesFile[CLDFB_NO_CHANNELS_MAX]; float parametricReverberationEneCorrectionsFile[CLDFB_NO_CHANNELS_MAX]; float parametricEarlyPartEneCorrectionFile[CLDFB_NO_CHANNELS_MAX]; - - FILE *input_param_bin_file = NULL; +#endif full_in_param_bin_path = (char *) malloc( sizeof( char ) * ( strlen( input_param_bin_path ) + strlen( input_param_bin_file_name ) + 2 ) ); if ( full_in_param_bin_path == NULL ) @@ -1236,6 +1374,84 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtf_data_size = 0; +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + + input_param_bin_file = fopen( full_in_param_bin_path, "rb" ); + + if ( input_param_bin_file != NULL ) + { + uint16_t hrtf_sh_channels, hrtf_num_bins, cldfb_no_channels_max; + + fseek( input_param_bin_file, 0, SEEK_END ); + hrtf_data_size = ftell( input_param_bin_file ); + fseek( input_param_bin_file, 0, SEEK_SET ); + + // Allocate memory + *hrtf_size = sizeof( ivas_hrtfs_header_t ) + hrtf_data_size; + hrtf = (char *) malloc( *hrtf_size ); + if ( hrtf == NULL ) + { + fprintf( stderr, "Memory allocation for the block failed!\n\n" ); + fclose( input_param_bin_file ); + free( full_in_param_bin_path ); + *hrtf_size = -1; + return NULL; + } + + memset( hrtf, 0x00, *hrtf_size ); + hrtf_wptr = hrtf; + +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( is_fx == 1 ) + { + *( (int32_t *) ( hrtf_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_PARAMETRIC + DEFAULT_BIN_FILE_FX_FLAG; + } + else + { + *( (int32_t *) ( hrtf_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_PARAMETRIC; + } +#else + if ( is_fx == 1 ) + { + *( (int32_t *) ( hrtf_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM + DEFAULT_BIN_FILE_FX_FLAG; + } + else + { + *( (int32_t *) ( hrtf_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM; + } +#endif + hrtf_wptr += sizeof( int32_t ); + + // Decoder output format - not relevant parametric binaural renderer + *( (int32_t *) ( hrtf_wptr ) ) = BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED; + hrtf_wptr += sizeof( int32_t ); + + // Sampling Frequency + *( (int32_t *) ( hrtf_wptr ) ) = 48000; + hrtf_wptr += sizeof( int32_t ); + + // Raw data size + memcpy( hrtf_wptr, &( hrtf_data_size ), sizeof( uint32_t ) ); + hrtf_wptr += sizeof( uint32_t ); + + // Get the HRTF raw data + + if ( fread( hrtf_wptr, 1, hrtf_data_size, input_param_bin_file ) != hrtf_data_size ) + { + fprintf( stderr, "Reading of the mixer_conv hrtf failed!\n\n" ); + fclose( input_param_bin_file ); + free( hrtf ); + *hrtf_size = -1; + return NULL; + } + + fclose( input_param_bin_file ); + input_param_bin_file = NULL; + free( full_in_param_bin_path ); + full_in_param_bin_path = NULL; + } + +#else /* Binary file - block description : HRTFs @@ -1334,7 +1550,6 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) return NULL; } - // Write // Header [Declaration of the HRTF] @@ -1347,7 +1562,11 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) hrtf_wptr = hrtf; // Renderer type - we use only parametric room type here to cover both cases +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + *( (int32_t *) ( hrtf_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_PARAMETRIC; +#else *( (int32_t *) ( hrtf_wptr ) ) = HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM; +#endif hrtf_wptr += sizeof( int32_t ); // Decoder output format - not relevant parametric binaural renderer @@ -1362,7 +1581,6 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) memcpy( hrtf_wptr, &( hrtf_data_size ), sizeof( uint32_t ) ); hrtf_wptr += sizeof( uint32_t ); - // Write the HRTF raw data *( (uint16_t *) ( hrtf_wptr ) ) = HRTF_SH_CHANNELS; hrtf_wptr += sizeof( uint16_t ); @@ -1426,6 +1644,8 @@ char *create_hrtf_parametric( int32_t *hrtf_size ) memcpy( hrtf_wptr, &( parametricEarlyPartEneCorrection ), data_size_tmp ); // parametricEarlyPartEneCorrection hrtf_wptr += data_size_tmp; } +#endif + return hrtf; } @@ -1437,7 +1657,7 @@ int16_t get_crend_hrtf_tables( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INP { int16_t result = -1; uint16_t iChan, iIR, iIter, iIndex, max_num_iterations; - uint16_t total_num_fsamp_per_iteration, total_num_fsamp_per_iteration_diff; + uint32_t total_num_fsamp_per_iteration, total_num_fsamp_per_iteration_diff; crend_hrtf_tables_pointers hrtf_table_ptrs_out; crend_hrtf_tables_dimensions hrtf_table_dims_out; @@ -1844,6 +2064,82 @@ int16_t get_crend_hrtf_tables( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INP return result; } +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT +/*---------------------------------------------------------------------* + * compute_crend_hrtf_data_size_fx() + * + *---------------------------------------------------------------------*/ +int32_t compute_crend_hrtf_data_size_fx( crend_hrtf_tables_pointers *hrtf_table_ptrs, crend_hrtf_tables_dimensions *hrtf_table_dims ) +{ + int32_t hrtf_data_size = 0; + int32_t iChan, iIR, iIndex, iIter; + + if ( ( hrtf_table_ptrs == NULL ) || ( hrtf_table_dims == NULL ) ) + { + return 0; + } + + hrtf_data_size += sizeof( Word16 ); // latency_s factor Q + hrtf_data_size += sizeof( Word32 ); // latency_s + hrtf_data_size += sizeof( uint16_t ); // max_num_ir + hrtf_data_size += sizeof( uint16_t ); // BINAURAL_CHANNELS + hrtf_data_size += sizeof( int16_t ); // max_num_iterations + hrtf_data_size += hrtf_table_dims->max_num_ir * BINAURAL_CHANNELS * sizeof( uint16_t ); // num_iterations + hrtf_data_size += hrtf_table_dims->max_num_ir * BINAURAL_CHANNELS * hrtf_table_dims->max_num_iterations * sizeof( uint16_t ); // pIndex_frequency_max + + hrtf_data_size += sizeof( int16_t ); // max_num_iterations_diffuse + if ( hrtf_table_dims->max_num_iterations_diffuse != 0 ) + { + hrtf_data_size += BINAURAL_CHANNELS * sizeof( uint16_t ); // num_iterations_diffuse + // pIndex_frequency_max_diffuse : The size depends on num_iterations_diffuse + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + hrtf_data_size += hrtf_table_ptrs->num_iterations_diffuse[iChan] * sizeof( uint16_t ); + } + } + + hrtf_data_size += sizeof( uint16_t ); // index_frequency_max_diffuse + hrtf_data_size += sizeof( Word16 ); // inv_diffuse_weight factor Q + hrtf_data_size += hrtf_table_dims->max_num_ir * BINAURAL_CHANNELS * sizeof( Word16 ); // inv_diffuse_weight +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration +#else + hrtf_data_size += sizeof( uint16_t ); // max_total_num_fsamp_per_iteration +#endif + + hrtf_data_size += sizeof( Word16 ); // filters factor Q + // coeff_re & coeff_im : The size depends on pIndex_frequency_max + for ( iIR = 0, iIndex = 0; iIR < hrtf_table_dims->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + for ( iIter = 0; iIter < hrtf_table_ptrs->num_iterations[iIR * BINAURAL_CHANNELS + iChan]; iIter++ ) + { + hrtf_data_size += 2 * hrtf_table_ptrs->pIndex_frequency_max[iIndex++] * sizeof( Word32 ); // 2* : re & im + } + } + } + +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration_diff +#else + hrtf_data_size += sizeof( uint16_t ); // max_total_num_fsamp_per_iteration_diff +#endif + if ( hrtf_table_dims->max_total_num_fsamp_per_iteration_diff != 0 ) + { + // coeff_diffuse_re & coeff_diffuse_im : The size depends on pIndex_frequency_max + for ( iChan = 0, iIndex = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + for ( iIter = 0; iIter < hrtf_table_ptrs->num_iterations_diffuse[iChan]; iIter++ ) + { + hrtf_data_size += 2 * hrtf_table_ptrs->pIndex_frequency_max_diffuse[iIndex++] * sizeof( Word32 ); // 2* : re & im + } + } + } + + return hrtf_data_size; +} +#endif /*---------------------------------------------------------------------* * compute_crend_hrtf_data_size() * @@ -1876,9 +2172,13 @@ int32_t compute_crend_hrtf_data_size( crend_hrtf_tables_pointers *hrtf_table_ptr } } - hrtf_data_size += sizeof( uint16_t ); // index_frequency_max_diffuse + hrtf_data_size += sizeof( uint16_t ); // index_frequency_max_diffuse hrtf_data_size += hrtf_table_dims->max_num_ir * BINAURAL_CHANNELS * sizeof( float ); // inv_diffuse_weight +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration +#else hrtf_data_size += sizeof( uint16_t ); // max_total_num_fsamp_per_iteration +#endif // coeff_re & coeff_im : The size depends on pIndex_frequency_max for ( iIR = 0, iIndex = 0; iIR < hrtf_table_dims->max_num_ir; iIR++ ) { @@ -1891,7 +2191,11 @@ int32_t compute_crend_hrtf_data_size( crend_hrtf_tables_pointers *hrtf_table_ptr } } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration_diff +#else hrtf_data_size += sizeof( uint16_t ); // max_total_num_fsamp_per_iteration_diff +#endif if ( hrtf_table_dims->max_total_num_fsamp_per_iteration_diff != 0 ) { // coeff_diffuse_re & coeff_diffuse_im : The size depends on pIndex_frequency_max @@ -2038,7 +2342,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD if ( rend_type == HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD || rend_type == HRTF_READER_RENDERER_BINAURAL_REVERB_ALL || rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV || rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM || +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + rend_type == HRTF_READER_RENDERER_BINAURAL_PARAMETRIC ) +#else rend_type == HRTF_READER_RENDERER_BINAURAL_PARAMETRIC || rend_type == HRTF_READER_RENDERER_BINAURAL_PARAMETRIC_ROOM ) +#endif { return 0; } @@ -2062,7 +2370,14 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD return -1; } +#ifdef FLOAT_FIX_POINT_HRTF_FILE_FORMAT + if ( rend_type & DEFAULT_BIN_FILE_FX_FLAG ) + hrtf_data_size = compute_crend_hrtf_data_size_fx( &tabs_ptrs, &tabs_dims ); + else + hrtf_data_size = compute_crend_hrtf_data_size( &tabs_ptrs, &tabs_dims ); +#else hrtf_data_size = compute_crend_hrtf_data_size( &tabs_ptrs, &tabs_dims ); +#endif if ( hrtf_data_size != hrtf_size_in ) { fprintf( stderr, "check_hrtf_data of binary file failed: bad hrtf_data_size!\n\n" ); @@ -2073,13 +2388,21 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD hrtf_data_in_rptr = hrtf_data_in; - // latency_s +// latency_s +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( ( *( tabs_ptrs.latency_s ) - ( *( (Word32 *) ( hrtf_data_in_rptr ) ) ) * powf( 2.f, -31.f ) ) > 1e-9f ) +#else if ( ( *( tabs_ptrs.latency_s ) - *( (float *) ( hrtf_data_in_rptr ) ) ) > 1e-9f ) +#endif { fprintf( stderr, "check_hrtf_data of binary file failed: bad latency_s!\n\n" ); return -1; } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_in_rptr += sizeof( Word32 ); +#else hrtf_data_in_rptr += sizeof( float ); +#endif // max_num_ir if ( tabs_dims.max_num_ir != *( (uint16_t *) ( hrtf_data_in_rptr ) ) ) @@ -2164,7 +2487,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD hrtf_data_in_rptr += sizeof( uint16_t ); // inv_diffuse_weight +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ctrl_size = tabs_dims.max_num_ir * BINAURAL_CHANNELS * sizeof( Word16 ); +#else ctrl_size = tabs_dims.max_num_ir * BINAURAL_CHANNELS * sizeof( float ); +#endif if ( memcmp( tabs_ptrs.inv_diffuse_weight, hrtf_data_in_rptr, ctrl_size ) != 0 ) { fprintf( stderr, "check_hrtf_data of binary file failed: bad inv_diffuse_weight!\n\n" ); @@ -2180,8 +2507,12 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD }*/ hrtf_data_in_rptr += ctrl_size; - // max_total_num_fsamp_per_iteration +// max_total_num_fsamp_per_iteration +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( tabs_dims.max_total_num_fsamp_per_iteration != *( (uint32_t *) ( hrtf_data_in_rptr ) ) ) +#else if ( tabs_dims.max_total_num_fsamp_per_iteration != *( (uint16_t *) ( hrtf_data_in_rptr ) ) ) +#endif { fprintf( stderr, "check_hrtf_data of binary file failed: bad max_total_num_fsamp_per_iteration!\n\n" ); return -1; @@ -2196,7 +2527,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD coeff_rptr = tabs_ptrs.coeff_re + ( iIR * BINAURAL_CHANNELS + iChan ) * tabs_dims.max_total_num_fsamp_per_iteration; for ( iIter = 0; iIter < tabs_ptrs.num_iterations[iIR * BINAURAL_CHANNELS + iChan]; iIter++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ctrl_size = tabs_ptrs.pIndex_frequency_max[iIndex] * sizeof( Word32 ); +#else ctrl_size = tabs_ptrs.pIndex_frequency_max[iIndex] * sizeof( float ); +#endif if ( memcmp( coeff_rptr, hrtf_data_in_rptr, ctrl_size ) != 0 ) { fprintf( stderr, "check_hrtf_data of binary file failed: bad coeff_re!\n\n" ); @@ -2225,7 +2560,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD coeff_rptr = tabs_ptrs.coeff_im + ( iIR * BINAURAL_CHANNELS + iChan ) * tabs_dims.max_total_num_fsamp_per_iteration; for ( iIter = 0; iIter < tabs_ptrs.num_iterations[iIR * BINAURAL_CHANNELS + iChan]; iIter++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ctrl_size = tabs_ptrs.pIndex_frequency_max[iIndex] * sizeof( Word32 ); +#else ctrl_size = tabs_ptrs.pIndex_frequency_max[iIndex] * sizeof( float ); +#endif if ( memcmp( coeff_rptr, hrtf_data_in_rptr, ctrl_size ) != 0 ) { fprintf( stderr, "check_hrtf_data of binary file failed: bad coeff_re!\n\n" ); @@ -2246,7 +2585,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD } // max_total_num_fsamp_per_iteration_diff +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( tabs_dims.max_total_num_fsamp_per_iteration_diff != *( (uint32_t *) ( hrtf_data_in_rptr ) ) ) +#else if ( tabs_dims.max_total_num_fsamp_per_iteration_diff != *( (uint16_t *) ( hrtf_data_in_rptr ) ) ) +#endif { fprintf( stderr, "check_hrtf_data of binary file failed: bad max_total_num_fsamp_per_iteration_diff!\n\n" ); return -1; @@ -2261,7 +2604,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD coeff_rptr = tabs_ptrs.coeff_diffuse_re + iChan * tabs_dims.max_total_num_fsamp_per_iteration_diff; for ( iIter = 0; iIter < tabs_ptrs.num_iterations_diffuse[iChan]; iIter++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ctrl_size = tabs_ptrs.pIndex_frequency_max_diffuse[iIndex] * sizeof( Word32 ); +#else ctrl_size = tabs_ptrs.pIndex_frequency_max_diffuse[iIndex] * sizeof( float ); +#endif if ( memcmp( coeff_rptr, hrtf_data_in_rptr, ctrl_size ) != 0 ) { fprintf( stderr, "check_hrtf_data of binary file failed: bad coeff_diffuse_re!\n\n" ); @@ -2286,7 +2633,11 @@ int16_t check_hrtf_data( HRTF_READER_RENDERER_TYPE rend_type, BINAURAL_INPUT_AUD coeff_rptr = tabs_ptrs.coeff_diffuse_im + iChan * tabs_dims.max_total_num_fsamp_per_iteration_diff; for ( iIter = 0; iIter < tabs_ptrs.num_iterations_diffuse[iChan]; iIter++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ctrl_size = tabs_ptrs.pIndex_frequency_max_diffuse[iIndex] * sizeof( Word32 ); +#else ctrl_size = tabs_ptrs.pIndex_frequency_max_diffuse[iIndex] * sizeof( float ); +#endif if ( memcmp( coeff_rptr, hrtf_data_in_rptr, ctrl_size ) != 0 ) { fprintf( stderr, "check_hrtf_data of binary file failed: bad coeff_diffuse_im!\n\n" ); diff --git a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin index ffb4662687d6d2fa0e9cab79dd8bed54a3065ea5..97f7cfdf50ac4f9590a855cef9802fb74a0f26be 100644 --- a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin +++ b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:600f05865baeeb01c6435725f87c6a91e6e75e481ffae2ec3d6a7c62aba5fc7c -size 1971974 +oid sha256:41719cf6eeb2b627a48e30a9d0eb0375f2041730ef29c35e23af3162abe37ff7 +size 1971934 diff --git a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin index 97190b44f8bc0e595ef3d5e9e22e02893056ba0c..0c87defe8cd12f6e3d923dcf2e377cd9b090cfca 100644 --- a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin +++ b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cda90cc841793f0a1ed76b580e46b9989564b055b664ed6746ebfa0033a74f2b -size 2430778 +oid sha256:84545fbcc27f8123f4c98f2188794797565e00b3ac76d133f6c24eebab9f7f29 +size 2430738 diff --git a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin index e1f6981162b9f9f917b78e4f6b342e803dc8a8c4..68cae9bc10e4a14b76e8ce804759db58f1311b47 100644 --- a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin +++ b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1654ead069a420b97af8755edbb1c358806aa3c5c07db3113789fe0942642de -size 2673946 +oid sha256:ef00e531e26972dd3788ad98378a6224f288d90ddd0536aefe546dccbd835bc2 +size 2673906 diff --git a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_16kHz.bin b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_16kHz.bin index 20c688d2da51b9bdcbfed510f0c86503dfc4bde6..13787ec393cc381f9b77ec36760d2f5ed1e6c0e8 100644 --- a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_16kHz.bin +++ b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_16kHz.bin @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c839dcbdcfb7de23b725325770a07de3fe0144dc56f0ba7b4a9627bc912c2547 -size 1771166 +oid sha256:420704e8c05cd809f8448c1797b3cd2e69df0deb7ebe229b51ff0b54bbf99339 +size 1771126 diff --git a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_32kHz.bin b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_32kHz.bin index c92f4c2af0b29bee7ce6e66ac3b30bda3ee3f39e..9b7593a1d58bda1b358b3e407cbbb7c32ad143e1 100644 --- a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_32kHz.bin +++ b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_32kHz.bin @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c88daaf248bb36ac11d0aa320b18ce87019ef6ad9fab6ac2b7f064b27048aac -size 2107682 +oid sha256:5f26a82e286d6cadac49bd448bb4b621ff6381cb9c0be91a85b6723761f1c676 +size 2107642 diff --git a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_48kHz.bin b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_48kHz.bin index 61f226bca4ba61441e73905206a3a2b4e9f0741c..8e7ad080a4207d1721e3b0a1bd440303a28503b3 100644 --- a/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_48kHz.bin +++ b/scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_51_brir-lc_48kHz.bin @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed7e4b9f3306e7aecd2edf19b7ca9fb62240031fa248b26ad7c606fef36a20fe -size 2343650 +oid sha256:7d72291e29de622a681635c11f8acceabbdfaec91e81a82146859b8b0d5ca2c8 +size 2343610 diff --git a/scripts/binauralRenderer_interface/clearButKeepNeededVariables.m b/scripts/binauralRenderer_interface/clearButKeepNeededVariables.m index f324edabb8f163f7407bc9a9e14221af27b9a346..49a020dcea7f49b85edf958c90c37920bd8d0e2d 100644 --- a/scripts/binauralRenderer_interface/clearButKeepNeededVariables.m +++ b/scripts/binauralRenderer_interface/clearButKeepNeededVariables.m @@ -1 +1 @@ -clear -regexp ^((?!writeRomFileOutput|writeBinaryOutput|writeEachRendererBinaryOutput|rom_file|bin_file|hrir_file|brir_file|ivas_path|binary_path|output_bin_name|param_bin_file|fastconv_bin_file|td_binary_file|binary_name|rom_path).)*$ +clear -regexp ^((?!writeRomFileOutput|writeBinaryOutput|generate_BE|generateBinaryFile_fx|generateCustomBinaryFile|writeEachRendererBinaryOutput|rom_file|bin_file|hrir_file|brir_file|ivas_path|binary_path|output_bin_name|param_bin_file|fastconv_bin_file|td_binary_file|binary_name|rom_path).)*$ diff --git a/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m index 75cb373cc96071b8b732883a6c58d9cdad1cdddc..37ec643f6351b3e1663b0e3daa817370fecbc6bd 100644 --- a/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m +++ b/scripts/binauralRenderer_interface/fastconv/generate_tables_for_fastconv.m @@ -49,6 +49,15 @@ end if ~exist("writeBinaryOutput",'var') writeBinaryOutput = true; end +if ~exist("generateCustomBinaryFile",'var') + generateCustomBinaryFile = false; +end +if ~exist("generateBinaryFile_fx",'var') + generateBinaryFile_fx = false; +end +if ~exist("generate_BE",'var') + generate_BE = true; +end if ~exist("rom_file",'var') rom_file = fullfile('.', 'ivas_rom_binauralRenderer.c'); end @@ -84,11 +93,32 @@ FastConv_SD_IR = SD_2_ROM(hrir_file); %% Generate C-code tables for RENDERER_BINAURAL_FASTCONV_ROOM (SD) disp('Processing BRIRs (SD) for FastConv renderer...'); FastConv_SD_BRIR = generate_BRIR_CLDFB_FASTCONV(brir_file); +if generateCustomBinaryFile == true + FastConv_SD_BRIR.rev_param.rt60 = FastConv_SD_BRIR.rev_param.rt60 * 2; + FastConv_SD_BRIR.rev_param.nrgLr = FastConv_SD_BRIR.rev_param.nrgLr * 2; +end -if writeRomFileOutput - write_fastconv_rom_table(rom_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); +%% compute scaling factor and ste floating point precision to word32 +if generate_BE == false + [FastConv_SHD_IR_FOA.IR, FastConv_SHD_IR_FOA.factorQ] = make_be_with_fx(FastConv_SHD_IR_FOA.IR,31); + [FastConv_SHD_IR_HOA2.IR, FastConv_SHD_IR_HOA2.factorQ] = make_be_with_fx(FastConv_SHD_IR_HOA2.IR,31); + [FastConv_SHD_IR_HOA3.IR, FastConv_SHD_IR_HOA3.factorQ] = make_be_with_fx(FastConv_SHD_IR_HOA3.IR,31); + [FastConv_SD_IR.IR, FastConv_SD_IR.factorQ] = make_be_with_fx(FastConv_SD_IR.IR,31); + [FastConv_SD_BRIR.IR, FastConv_SD_BRIR.factorQ] = make_be_with_fx(FastConv_SD_BRIR.IR,31); + [FastConv_SD_BRIR.rev_param.rt60, FastConv_SD_BRIR.factorQ_rt60] = make_be_with_fx(FastConv_SD_BRIR.rev_param.rt60,15); + [FastConv_SD_BRIR.rev_param.nrgLr, FastConv_SD_BRIR.factorQ_nrgLr] = make_be_with_fx(FastConv_SD_BRIR.rev_param.nrgLr,15); + if writeRomFileOutput + write_fastconv_rom_table(rom_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); + end +else + if writeRomFileOutput + write_fastconv_rom_table_BE(rom_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); + end end if writeBinaryOutput write_fastconv_binary_data(ivas_path, bin_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); + if generateBinaryFile_fx + write_fastconv_binary_data_fx(ivas_path, bin_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR); + end end diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data_fx.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data_fx.m new file mode 100644 index 0000000000000000000000000000000000000000..1fe83b038b968318ff7d52fdeeee5c30ada15def --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_binary_data_fx.m @@ -0,0 +1,333 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +% contributors to this repository. All Rights Reserved. +% +% This software is protected by copyright law and by international treaties. +% The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +% contributors to this repository retain full ownership rights in their respective contributions in +% the software. This notice grants no license of any kind, including but not limited to patent +% license, nor is any license granted by implication, estoppel or otherwise. +% +% Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +% contributions. +% +% This software is provided "AS IS", without any express or implied warranties. The software is in the +% development stage. It is intended exclusively for experts who have experience with such software and +% solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +% and fitness for a particular purpose are hereby disclaimed and excluded. +% +% Any dispute, controversy or claim arising under or in relation to providing this software shall be +% submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +% accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +% the United Nations Convention on Contracts on the International Sales of Goods. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function write_fastconv_binary_data_fx(ivas_path, bin_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR) +% +% Writes HRIR & BRIR based data for FastConv binaural renderer into a binary file. +% +% write_fastconv_binary_data(rom_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR) +% +% filename : string +% name of the file to be written +% +% +% Output file format: +% Header [Declaration of the HRTF] +% Renderer type (int32_t) : See "RENDERER_TYPE" +% Decoder output format (int32_t) : See "BINAURAL_INPUT_AUDIO_CONFIG" +% Sampling Frequency (int32_t) +% Raw data size (uint32_t) +% +% HRIRs +% factorQ => uint16_t +% latency_s => uint32_t +% BINAURAL_CONVBANDS => uint16_t +% num_channels => uint16_t +% BINAURAL_NTAPS => uint16_t +% factorQ => uint16_t +% leftHRIRReal => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% leftHRIRImag => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightHRIRReal => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightHRIRImag => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% +% BRIRs +% factorQ => uint16_t +% latency_s => float32 +% num_channels => uint16_t +% BINAURAL_NTAPS_MAX => uint16_t +% factorQ => uint16_t +% factorQ => uint16_t +% leftBRIRReal => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% leftBRIRImag => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightBRIRReal => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% rightBRIRImag => int32_t[BINAURAL_CONVBANDS][num_channels][num_taps] +% CLDFB_NO_CHANNELS_MAX => uint16_t +% factorQ => uint16_t +% fastConvReverberationTimes => int16_t[CLDFB_NO_CHANNELS_MAX] +% fastConvReverberationEneCorrections => int16_t[CLDFB_NO_CHANNELS_MAX] +% + +bin_file = [erase(bin_file,'.bin') '_fx.bin' ]; + +[f_id, err_msg] = fopen(bin_file, 'wb'); + +if f_id == -1 + error('Could not open file %s for writing. Error message:\n%s', filename, err_msg); +end + +%% File header +% We need to get the chunksize of all IRs to get total size +% SHD HRIRs +% FOA +IR = FastConv_SHD_IR_FOA; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header(ivas_path,'HRTF_READER_RENDERER_BINAURAL_FASTCONV', ['BINAURAL_INPUT_AUDIO_CONFIG_' IR.order]); +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SHD_IR_FOA = IR; + +% HOA2 +IR = FastConv_SHD_IR_HOA2; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header(ivas_path, 'HRTF_READER_RENDERER_BINAURAL_FASTCONV', ['BINAURAL_INPUT_AUDIO_CONFIG_' IR.order]); +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SHD_IR_HOA2 = IR; + +% HOA3 +IR = FastConv_SHD_IR_HOA3; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header(ivas_path, 'HRTF_READER_RENDERER_BINAURAL_FASTCONV', ['BINAURAL_INPUT_AUDIO_CONFIG_' IR.order]); +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SHD_IR_HOA3 = IR; + +% SD HRIRs +IR = FastConv_SD_IR; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +header = get_ivas_binary_header(ivas_path, 'HRTF_READER_RENDERER_BINAURAL_FASTCONV', 'BINAURAL_INPUT_AUDIO_CONFIG_COMBINED'); +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * binaural_ntaps * 4 ); % HRTF L/R Re/Im + +IR.header = header; +FastConv_SD_IR = IR; + +% SD BRIRs +IR = FastConv_SD_BRIR; +[~, binaural_convbands, num_channels, ~] = size(IR.IR); +cldfb_no_channels_max = IR.rev_param.kAna; + +header = get_ivas_binary_header(ivas_path, 'HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM', 'BINAURAL_INPUT_AUDIO_CONFIG_COMBINED'); +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4; % latency_s +header.chunksize = header.chunksize + 2; % BINAURAL_CONVBANDS +header.chunksize = header.chunksize + 2; % num_channels +header.chunksize = header.chunksize + 2; % num_taps +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + 4 * (binaural_convbands * num_channels * IR.rev_param.NFilter * 4 ); % HRTF L/R Re/Im +header.chunksize = header.chunksize + 2; % CLDFB_NO_CHANNELS_MAX +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + cldfb_no_channels_max * 2; % rt60 +header.chunksize = header.chunksize + 2; % factorQ +header.chunksize = header.chunksize + cldfb_no_channels_max * 2; % nrgLr + +IR.header = header; +FastConv_SD_BRIR = IR; + +% calculate the size of all chunks +HRTFs = {FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR}; +hrtf_data_size = 0; +total_file_size = 0; +for i = 1:length(HRTFs) + hrtf_data_size = hrtf_data_size + HRTFs{i}.header.chunksize; + total_file_size = total_file_size + 4 * 4; % chunk header 4 (u)int32 values +end + +total_file_size = total_file_size + 8; % 'IVASHRTF' (char[8]) +total_file_size = total_file_size + 4; % file size (int32) +total_file_size = total_file_size + 2; % number of HRTFs in file (int16) +total_file_size = total_file_size + 4; % HRTF size (int32) +total_file_size = total_file_size + hrtf_data_size; % size of all HRTF data chunks + +fwrite(f_id, 'IVASHRTF', 'char'); % identifier +fwrite(f_id, total_file_size, 'int32'); % file size +fwrite(f_id, length(HRTFs), 'int16'); % number of HRTFs +fwrite(f_id, hrtf_data_size, 'int32'); % max data size (bytes to read after this header) + +%% HRIRs + +% SHD HRIRs +SHD_HRIRs = {FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3}; +for i = 1:length(SHD_HRIRs) + IR = SHD_HRIRs{i}; + [~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + + % write header for this chunk + fwrite(f_id, IR.header.renderer_type, 'int32'); + fwrite(f_id, IR.header.in_fmt, 'int32'); + fwrite(f_id, IR.header.fs, 'int32'); + fwrite(f_id, IR.header.chunksize, 'uint32'); + + factorQ = int16(floor( double(31) - log( IR.latency_s ) / log( 2. ) )); + IR.latency_s = IR.latency_s .* (2.^double(factorQ)); + fwrite(f_id, int16(factorQ), 'uint16'); + fwrite(f_id, int32(IR.latency_s), 'int32'); + fwrite(f_id, binaural_convbands, 'uint16'); + fwrite(f_id, num_channels, 'uint16'); + fwrite(f_id, binaural_ntaps, 'uint16'); + + fwrite(f_id, IR.factorQ, 'uint16'); + IR.IR = IR.IR .* (2.^double(IR.factorQ)); + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(real(squeeze(IR.IR(1, band, ch, :)))), 'int32'); + end + end + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(imag(squeeze(IR.IR(1, band, ch, :)))), 'int32'); + end + end + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(real(squeeze(IR.IR(2, band, ch, :)))), 'int32'); + end + end + for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(imag(squeeze(IR.IR(2, band, ch, :)))), 'int32'); + end + end +end + +% SD HRIRs +IR = FastConv_SD_IR; +[~, binaural_convbands, num_channels, binaural_ntaps] = size(IR.IR); + +% write header for this chunk +fwrite(f_id, IR.header.renderer_type, 'int32'); +fwrite(f_id, IR.header.in_fmt, 'int32'); +fwrite(f_id, IR.header.fs, 'int32'); +fwrite(f_id, IR.header.chunksize, 'uint32'); + +factorQ = int16(floor( double(31) - log( IR.latency_s ) / log( 2. ) )); +IR.latency_s = IR.latency_s .* (2.^double(factorQ)); +fwrite(f_id, factorQ, 'uint16'); +fwrite(f_id, int32(IR.latency_s), 'int32'); +fwrite(f_id, binaural_convbands, 'uint16'); +fwrite(f_id, num_channels, 'uint16'); +fwrite(f_id, binaural_ntaps, 'uint16'); +fwrite(f_id, IR.factorQ, 'uint16'); +IR.IR = IR.IR .* (2.^double(IR.factorQ)); +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(real(squeeze(IR.IR(1, band, ch, :)))), 'int32'); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(imag(squeeze(IR.IR(1, band, ch, :)))), 'int32'); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(real(squeeze(IR.IR(2, band, ch, :)))), 'int32'); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(imag(squeeze(IR.IR(2, band, ch, :)))), 'int32'); + end +end + + +% SD BRIRs +IR = FastConv_SD_BRIR; +[~, binaural_convbands, num_channels, ~] = size(IR.IR); +cldfb_no_channels_max = IR.rev_param.kAna; + +% write header for this chunk +fwrite(f_id, IR.header.renderer_type, 'int32'); +fwrite(f_id, IR.header.in_fmt, 'int32'); +fwrite(f_id, IR.header.fs, 'int32'); +fwrite(f_id, IR.header.chunksize, 'uint32'); + +factorQ = int16(floor( double(31) - log( IR.rev_param.latency_s ) / log( 2. ) )); +IR.rev_param.latency_s = IR.rev_param.latency_s .* (2.^double(factorQ)); +fwrite(f_id, factorQ, 'uint16'); +fwrite(f_id, int32(IR.rev_param.latency_s), 'int32'); +fwrite(f_id, binaural_convbands, 'uint16'); +fwrite(f_id, num_channels, 'uint16'); +fwrite(f_id, IR.rev_param.NFilter, 'uint16'); +fwrite(f_id, IR.factorQ, 'uint16'); +IR.IR = IR.IR .* (2.^double(IR.factorQ)); +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(real(squeeze(IR.IR(1, band, ch, 1:IR.rev_param.NFilter)))), 'int32' ); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(imag(squeeze(IR.IR(1, band, ch, 1:IR.rev_param.NFilter)))), 'int32' ); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(real(squeeze(IR.IR(2, band, ch, 1:IR.rev_param.NFilter)))), 'int32' ); + end +end +for band = 1:binaural_convbands + for ch = 1:num_channels + fwrite(f_id, int32(imag(squeeze(IR.IR(2, band, ch, 1:IR.rev_param.NFilter)))), 'int32' ); + end +end + +fwrite(f_id, cldfb_no_channels_max, 'uint16'); +fwrite(f_id, IR.factorQ_rt60, 'uint16'); +IR.rev_param.rt60 = IR.rev_param.rt60 .* (2.^double(IR.factorQ_rt60)); +fwrite(f_id, int16(IR.rev_param.rt60), 'int16'); +fwrite(f_id, IR.factorQ_nrgLr, 'uint16'); +IR.rev_param.nrgLr = IR.rev_param.nrgLr .* (2.^double(IR.factorQ_nrgLr)); +fwrite(f_id, int16(IR.rev_param.nrgLr), 'int16'); + +fclose(f_id); + +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m index 5feeaf5459402d9c3b24c8dff7b295c1e5c04af6..53005fdd8165711f41b2a794464bf1799fd7371c 100644 --- a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table.m @@ -44,54 +44,54 @@ function write_fastconv_rom_table(output_file, FastConv_SHD_IR_FOA, FastConv_SHD %% HRIRs (SHD) % HOA3 - fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_HOA3.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_HOA3.latency_s); - writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); - writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); - writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); - writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); + fprintf(fid, ['const uint32_t FASTCONV_' FastConv_SHD_IR_HOA3.order '_latency_s = 0x%tx;\n'], FastConv_SHD_IR_HOA3.latency_s); + writeData3L(fid, ['const uint32_t leftHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx', real(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); + writeData3L(fid, ['const uint32_t leftHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',imag(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); + writeData3L(fid, ['const uint32_t rightHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',real(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); + writeData3L(fid, ['const uint32_t rightHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',imag(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); % HOA2 - fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_HOA2.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_HOA2.latency_s); - writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); - writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); - writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); - writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); + fprintf(fid, ['const uint32_t FASTCONV_' FastConv_SHD_IR_HOA2.order '_latency_s = 0x%tx;\n'], FastConv_SHD_IR_HOA2.latency_s); + writeData3L(fid, ['const uint32_t leftHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',real(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); + writeData3L(fid, ['const uint32_t leftHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',imag(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); + writeData3L(fid, ['const uint32_t rightHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'0x%tx', real(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); + writeData3L(fid, ['const uint32_t rightHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',imag(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); % FOA - fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_FOA.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_FOA.latency_s); - writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); - writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); - writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], real(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); - writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], imag(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); + fprintf(fid, ['const uint32_t FASTCONV_' FastConv_SHD_IR_FOA.order '_latency_s = 0x%tx;\n'], FastConv_SHD_IR_FOA.latency_s); + writeData3L(fid, ['const uint32_t leftHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',real(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); + writeData3L(fid, ['const uint32_t leftHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',imag(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); + writeData3L(fid, ['const uint32_t rightHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',real(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); + writeData3L(fid, ['const uint32_t rightHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '0x%tx',imag(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); %% HRIRs (SD) - fprintf(fid, 'const float FASTCONV_HRIR_latency_s = %10.9ff;\n', FastConv_SD_IR.latency_s); - writeData3L(fid, 'const float leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', real(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); - writeData3L(fid, 'const float leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', imag(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); - writeData3L(fid, 'const float rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', real(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); - writeData3L(fid, 'const float rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', imag(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); + fprintf(fid, 'const uint32_t FASTCONV_HRIR_latency_s = 0x%tx;\n', FastConv_SD_IR.latency_s); + writeData3L(fid, 'const uint32_t leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', '0x%tx',real(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); + writeData3L(fid, 'const uint32_t leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', '0x%tx',imag(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); + writeData3L(fid, 'const uint32_t rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', '0x%tx',real(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); + writeData3L(fid, 'const uint32_t rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', '0x%tx',imag(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); %% BRIRs (SD) fprintf(fid, '/* Binaural rendering data set based on BRIRs \n'); fprintf(fid, ' * Tables derived from Mozart IIS BRIRs.*/\n'); - fprintf(fid, 'const float FASTCONV_BRIR_latency_s = %10.9ff;\n', FastConv_SD_BRIR.rev_param.latency_s); - writeData3L(fid, 'const float leftBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', real(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); - writeData3L(fid, 'const float leftBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', imag(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); - writeData3L(fid, 'const float rightBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', real(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); - writeData3L(fid, 'const float rightBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', imag(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + fprintf(fid, 'const uint32_t FASTCONV_BRIR_latency_s = 0x%tx;\n', FastConv_SD_BRIR.rev_param.latency_s); + writeData3L(fid, 'const uint32_t leftBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]','0x%tx', real(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const uint32_t leftBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', '0x%tx',imag(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const uint32_t rightBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]','0x%tx', real(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const uint32_t rightBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]','0x%tx', imag(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); % RT60 - fprintf(fid,'const float fastconvReverberationTimes[CLDFB_NO_CHANNELS_MAX] = \n{'); + fprintf(fid,'const uint32_t fastconvReverberationTimes[CLDFB_NO_CHANNELS_MAX] = \n{'); fprintf(fid,'\n\t'); for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna - fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.rt60(bandIdx),'f'); + fprintf(fid,'0x%tx, ', FastConv_SD_BRIR.rev_param.rt60(bandIdx)); end fprintf(fid,'\n};\n'); fprintf(fid,'\n\n'); % energyReverb - fprintf(fid,'const float fastconvReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = \n{'); + fprintf(fid,'const uint32_t fastconvReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = \n{'); fprintf(fid,'\n\t'); for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna - fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.nrgLr(bandIdx),'f'); + fprintf(fid,'0x%tx, ', FastConv_SD_BRIR.rev_param.nrgLr(bandIdx)); end fprintf(fid,'\n};\n'); fprintf(fid,'\n\n'); diff --git a/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table_BE.m b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table_BE.m new file mode 100644 index 0000000000000000000000000000000000000000..af255ab4f447d7e0014fa8824dbba2a05e135ed6 --- /dev/null +++ b/scripts/binauralRenderer_interface/fastconv/write_fastconv_rom_table_BE.m @@ -0,0 +1,101 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +% contributors to this repository. All Rights Reserved. +% +% This software is protected by copyright law and by international treaties. +% The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +% contributors to this repository retain full ownership rights in their respective contributions in +% the software. This notice grants no license of any kind, including but not limited to patent +% license, nor is any license granted by implication, estoppel or otherwise. +% +% Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +% contributions. +% +% This software is provided "AS IS", without any express or implied warranties. The software is in the +% development stage. It is intended exclusively for experts who have experience with such software and +% solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +% and fitness for a particular purpose are hereby disclaimed and excluded. +% +% Any dispute, controversy or claim arising under or in relation to providing this software shall be +% submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +% accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +% the United Nations Convention on Contracts on the International Sales of Goods. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function write_fastconv_rom_table(output_file, FastConv_SHD_IR_FOA, FastConv_SHD_IR_HOA2, FastConv_SHD_IR_HOA3, FastConv_SD_IR, FastConv_SD_BRIR) + % TODO move this to common script that writes all tables? + %% Open file and write header + if ismac + username = getenv('USER'); + else + username = getenv('username'); + end + fid = fopen(output_file, 'at'); + fprintf(fid, '/*\n'); + fprintf(fid, ' * Generated on %s with Matlab version %s by %s on %s\n', datetime("today"), version, username, computer); + fprintf(fid, '*/\n\n\n'); + + %% HRIRs (SHD) + % HOA3 + fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_HOA3.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_HOA3.latency_s); + writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', real(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); + writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '%+ff',imag(squeeze(FastConv_SHD_IR_HOA3.IR(1,:,:,:)))); + writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', real(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); + writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_HOA3.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA3.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', imag(squeeze(FastConv_SHD_IR_HOA3.IR(2,:,:,:)))); + % HOA2 + fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_HOA2.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_HOA2.latency_s); + writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', real(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); + writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', imag(squeeze(FastConv_SHD_IR_HOA2.IR(1,:,:,:)))); + writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', real(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); + writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_HOA2.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_HOA2.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', imag(squeeze(FastConv_SHD_IR_HOA2.IR(2,:,:,:)))); + % FOA + fprintf(fid, ['const float FASTCONV_' FastConv_SHD_IR_FOA.order '_latency_s = %10.9ff;\n'], FastConv_SHD_IR_FOA.latency_s); + writeData3L(fid, ['const float leftHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', real(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); + writeData3L(fid, ['const float leftHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'],'%+ff', imag(squeeze(FastConv_SHD_IR_FOA.IR(1,:,:,:)))); + writeData3L(fid, ['const float rightHRIRReal_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '%+ff',real(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); + writeData3L(fid, ['const float rightHRIRImag_' FastConv_SHD_IR_FOA.order '[BINAURAL_CONVBANDS][' FastConv_SHD_IR_FOA.order '_CHANNELS][BINAURAL_NTAPS_SBA]'], '%+ff',imag(squeeze(FastConv_SHD_IR_FOA.IR(2,:,:,:)))); + + %% HRIRs (SD) + fprintf(fid, 'const float FASTCONV_HRIR_latency_s = %10.9ff;\n', FastConv_SD_IR.latency_s); + writeData3L(fid, 'const float leftHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]','%+ff', real(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); + writeData3L(fid, 'const float leftHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]','%+ff', imag(squeeze(FastConv_SD_IR.IR(1,:,:,:)))); + writeData3L(fid, 'const float rightHRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]', '%+ff',real(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); + writeData3L(fid, 'const float rightHRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]','%+ff', imag(squeeze(FastConv_SD_IR.IR(2,:,:,:)))); + + %% BRIRs (SD) + fprintf(fid, '/* Binaural rendering data set based on BRIRs \n'); + fprintf(fid, ' * Tables derived from Mozart IIS BRIRs.*/\n'); + fprintf(fid, 'const float FASTCONV_BRIR_latency_s = %10.9ff;\n', FastConv_SD_BRIR.rev_param.latency_s); + writeData3L(fid, 'const float leftBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]','%+ff', real(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const float leftBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', '%+ff',imag(squeeze(FastConv_SD_BRIR.IR(1,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const float rightBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]', '%+ff',real(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + writeData3L(fid, 'const float rightBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]','%+ff', imag(squeeze(FastConv_SD_BRIR.IR(2,:,:,1:FastConv_SD_BRIR.rev_param.NFilter)))); + + % RT60 + fprintf(fid,'const float fastconvReverberationTimes[CLDFB_NO_CHANNELS_MAX] = \n{'); + fprintf(fid,'\n\t'); + for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna + fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.rt60(bandIdx),'f'); + end + fprintf(fid,'\n};\n'); + fprintf(fid,'\n\n'); + + % energyReverb + fprintf(fid,'const float fastconvReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = \n{'); + fprintf(fid,'\n\t'); + for bandIdx = 1:FastConv_SD_BRIR.rev_param.kAna + fprintf(fid,'%f%s, ', FastConv_SD_BRIR.rev_param.nrgLr(bandIdx),'f'); + end + fprintf(fid,'\n};\n'); + fprintf(fid,'\n\n'); + + fclose(fid); + +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/generate_crend_ivas_tables_from_sofa.c b/scripts/binauralRenderer_interface/generate_crend_ivas_tables_from_sofa.c index 4a647690d8ce5de2efe2fb8c43a7b4ca5f11491f..03e23f345f2542985cc075910dee5a0d5347400e 100644 --- a/scripts/binauralRenderer_interface/generate_crend_ivas_tables_from_sofa.c +++ b/scripts/binauralRenderer_interface/generate_crend_ivas_tables_from_sofa.c @@ -68,13 +68,21 @@ * Constants *------------------------------------------------------------------------------------------*/ -#define MAX_DIFF_AZI 1 /* angle in degree */ -#define MAX_DIFF_ELE 10 /* angle in degree */ -#define DEFAULT_SAMPLERATE 48000 /* Hz */ -#define LAST_SAMPLERATE 16000 /* Hz */ -#define TEMPLTATE_C_ROM_FILE_NAME "ivas_license_header.template" -#define ROM_FILE_NAME "ivas_rom_binaural_crend_head" -#define FORMAT_FLOAT "%8.6f" +#define MAX_DIFF_AZI 1 /* angle in degree */ +#define MAX_DIFF_ELE 10 /* angle in degree */ +#define DEFAULT_SAMPLERATE 48000 /* Hz */ +#define LAST_SAMPLERATE 16000 /* Hz */ +#define TEMPLTATE_C_ROM_FILE_NAME "ivas_license_header.template" +#define ROM_FILE_NAME "ivas_rom_binaural_crend_head" +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +#define FORMAT_FLOAT "%a" +#define FORMAT_FLOAT_REVERB "%a" +#define FORMAT_FLOAT_LATENCY "%a" +#else +#define FORMAT_FLOAT "%8.6f" +#define FORMAT_FLOAT_REVERB "%8.6f" +#define FORMAT_FLOAT_LATENCY "%10.9ff" +#endif #define NUM_SAMPLES_PER_LINES 96 #define NUM_SAMPLES_PER_LINES_REVERB 9 #define DECLARATION_NAME "CRendBin" @@ -82,11 +90,6 @@ #define NUM_ITERATIONS_TO_ALLOW_OPTIM_5_MS 5 /* no optimisation if hrir length is lower then 20 ms*/ #define NUM_ITERATIONS_TO_ALLOW_OPTIM_20_MS 1 /* no optimisation if hrir length is lower then 20 ms*/ -int32_t sample_rates[3] = { DEFAULT_SAMPLERATE, 32000, 16000 }; /* Hz */ /* 8000 Hz not supported by mdft */ - -char *binary_file_path = NULL; -char *lib_rend_path = NULL; - #define DEFAULT_BINARY_FILE_NAME "crend" #ifdef _WIN32 #define DEFAULT_BINARY_FILE_PATH ".\\bin" @@ -119,8 +122,13 @@ typedef struct _crend_hrtf_tables_dimensions int16_t max_num_ir; int16_t max_num_iterations; int16_t max_num_iterations_diffuse; +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + uint32_t max_total_num_fsamp_per_iteration; + uint32_t max_total_num_fsamp_per_iteration_diff; +#else uint16_t max_total_num_fsamp_per_iteration; uint16_t max_total_num_fsamp_per_iteration_diff; +#endif } crend_hrtf_tables_dimensions; @@ -132,16 +140,32 @@ void usage_gen_crend_tables( void ); void get_ls_layout_config( AUDIO_CONFIG ls_layout_config, struct ivas_layout_config *ls_struct ); int generate_crend_ivas_tables_from_sofa( const char *sofa_file_path, ConfigReader *cfgReader ); void update_h_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ); +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len, int16_t factorQ[3] ); +void update_c_file_with_reverb( float *pEner_l, float *pEner_r, float *pCoherence, Word16 *pEner_l_fx, Word16 *pEner_r_fx, Word16 *pCoherence_fx, int16_t factorQ, const int32_t samplerate, const int16_t len ); +#else void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ); -int generate_reverb_ivas_tables_from_sofa( const char *file_path ); -void update_h_file_with_reverb( const int32_t samplerate ); void update_c_file_with_reverb( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate, const int16_t len ); +#endif +void update_h_file_with_reverb( const int32_t samplerate ); +int generate_reverb_ivas_tables_from_sofa( const char *file_path ); +extern Word32 float2Word32( float, Word16 ); +extern Word16 float2Word16( float, Word16 ); void get_binary_tables_dimensions( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hrtf_table_dims /*OUT*/ ); uint32_t compute_binary_size( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hrtf_table_dims ); -void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ); -void write_reverb_to_binary_file( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate ); +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +uint32_t compute_binary_size_fx( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hrtf_table_dims ); +ivas_error make_fx_be( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len, int16_t factorQ[3] ); +ivas_error make_reverb_fx_be( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate, Word16 *factorQ ); +#endif +ivas_error write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ); +ivas_error write_reverb_to_binary_file( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate ); +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +ivas_error write_binary_file_fx( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len, int16_t factorQ[3] ); +ivas_error write_reverb_to_binary_file_fx( float *pEner_l, float *pEner_r, float *pCoherence, Word16 factorQ, const int32_t samplerate ); +#endif /*---------------------------------------------------------------------* * @@ -221,7 +245,6 @@ void usage_gen_crend_tables( void ) fprintf( stdout, "\n" ); } - /*------------------------------------------------------------------------------------------* * Global variables *------------------------------------------------------------------------------------------*/ @@ -231,6 +254,9 @@ char *c_file_path = NULL; char *h_file_path = NULL; char *rom_file_name = NULL; uint16_t frame_len_ms = 5; +int32_t sample_rates[3] = { DEFAULT_SAMPLERATE, 32000, 16000 }; /* Hz */ /* 8000 Hz not supported by mdft */ +char *binary_file_path = NULL; +char *lib_rend_path = NULL; /*------------------------------------------------------------------------------------------* * Standalone Renderer program @@ -854,6 +880,7 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c double *sofa_delay_val = NULL; double *sofa_src_pos_val = NULL; double *sofa_src_pos_cart_val = NULL; + int iIR, iChan, iIter, offset; long sofa_sample_rate = 0; double a[3] = { 0 }; @@ -1251,10 +1278,8 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c } else { - ivas_set_hrtf_fr( &hrtf_data, ivas_hrtf, frame_len - , - mdft_scale_fact - ); + ivas_set_hrtf_fr( &hrtf_data, ivas_hrtf, frame_len, + mdft_scale_fact ); } hrtf_data.latency_s += 0.000000001f; @@ -1272,15 +1297,45 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c latency_48k_optim = hrtf_data.latency_s; } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + int16_t factorQ[3]; + make_fx_be( &hrtf_data, lscfg, sample_rates[indSR], frame_len, factorQ ); +#endif + if ( lib_rend_path != NULL ) { update_h_file( &hrtf_data, lscfg, sample_rates[indSR], frame_len ); +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + update_c_file( &hrtf_data, lscfg, sample_rates[indSR], frame_len, factorQ ); +#else update_c_file( &hrtf_data, lscfg, sample_rates[indSR], frame_len ); +#endif } if ( binary_file_path != NULL ) { - write_binary_file( &hrtf_data, lscfg, sample_rates[indSR], frame_len ); + if ( write_binary_file( &hrtf_data, lscfg, sample_rates[indSR], frame_len ) != IVAS_ERR_OK ) + { + mxDestroyArray( sofa ); + fprintf( stderr, "Write binary file error\n" ); + free( sofa_file_path ); + free( index_pos ); + free( ivas_hrtf ); + ivas_hrtf_close( &hrtf_data ); + return -1; + } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( write_binary_file_fx( &hrtf_data, lscfg, sample_rates[indSR], frame_len, factorQ ) != IVAS_ERR_OK ) + { + mxDestroyArray( sofa ); + fprintf( stderr, "Write binary file fx error\n" ); + free( sofa_file_path ); + free( index_pos ); + free( ivas_hrtf ); + ivas_hrtf_close( &hrtf_data ); + return -1; + } +#endif } if ( ivas_hrtf->latency_s[0] ) @@ -1316,7 +1371,6 @@ int generate_crend_ivas_tables_from_sofa( const char *file_path, ConfigReader *c } - #define IVAS_REVERB_FFT_SIZE_48K ( 512 ) #define IVAS_REVERB_FFT_SIZE_32K ( 512 ) #define IVAS_REVERB_FFT_SIZE_16K ( 256 ) @@ -1783,6 +1837,12 @@ int generate_reverb_ivas_tables_from_sofa( const char *file_path ) nr_fc_fft_filter = ( frame_len >> 1 ) + 1; float *p_avg_lr = NULL; float *pCoherence = NULL; +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + Word16 *p_avg_lr_fx = NULL; + Word16 *pCoherence_fx = NULL; + Word16 factorQ; +#endif + p_avg_lr = (float *) malloc( sizeof( float * ) * nr_fc_fft_filter * 2 ); pCoherence = (float *) malloc( sizeof( float * ) * nr_fc_fft_filter ); memset( p_avg_lr, 0, sizeof( float ) * nr_fc_fft_filter * 2 ); @@ -1828,14 +1888,30 @@ int generate_reverb_ivas_tables_from_sofa( const char *file_path ) ivas_reverb_get_hrtf_set_properties( pHrtf_set_l_re, pHrtf_set_l_im, pHrtf_set_r_re, pHrtf_set_r_im, IVAS_AUDIO_CONFIG_5_1, sofa_M, nr_fc_fft_filter, nr_fc_fft_filter, p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence ); +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + make_reverb_fx_be( p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence, sample_rates[indSR], &factorQ ); +#endif update_h_file_with_reverb( sample_rates[indSR] ); +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + update_c_file_with_reverb( p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence, p_avg_lr_fx, &p_avg_lr_fx[nr_fc_fft_filter], pCoherence_fx, factorQ, sample_rates[indSR], nr_fc_fft_filter ); +#else update_c_file_with_reverb( p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence, sample_rates[indSR], nr_fc_fft_filter ); - +#endif if ( binary_file_path != NULL ) { - write_reverb_to_binary_file( p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence, sample_rates[indSR] ); + if ( write_reverb_to_binary_file( p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence, sample_rates[indSR] ) != IVAS_ERR_OK ) + { + goto cleanup; + } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + if ( write_reverb_to_binary_file_fx( p_avg_lr, &p_avg_lr[nr_fc_fft_filter], pCoherence, factorQ, sample_rates[indSR] ) != IVAS_ERR_OK ) + { + goto cleanup; + } +#endif } + cleanup: for ( int i = 0; i < sofa_M; i++ ) { if ( pHrtf_set_l_re[i] ) @@ -1918,7 +1994,10 @@ void write_array_float_to_file( FILE *fp, float *vec, int32_t size_vec, int32_t for ( l = 0; l < sample_per_ligne; l++ ) { fprintf( fp, format, vec[k * sample_per_ligne + l] ); - fprintf( fp, "f, " ); + if ( strcmp( format, "%a" ) ) + fprintf( fp, "f, " ); + else + fprintf( fp, ", " ); } fprintf( fp, "\n" ); } @@ -1929,10 +2008,16 @@ void write_array_float_to_file( FILE *fp, float *vec, int32_t size_vec, int32_t for ( l = 0; l < remaining_samples - 1; l++ ) { fprintf( fp, format, vec[k * sample_per_ligne + l] ); - fprintf( fp, "f, " ); + if ( strcmp( format, "%a" ) ) + fprintf( fp, "f, " ); + else + fprintf( fp, ", " ); } fprintf( fp, format, vec[k * sample_per_ligne + l] ); - fprintf( fp, "f}" ); + if ( strcmp( format, "%a" ) ) + fprintf( fp, "f}" ); + else + fprintf( fp, "}" ); } /*---------------------------------------------------------------------* @@ -1989,10 +2074,122 @@ void write_array_uint16_to_file( FILE *fp, uint16_t *vec, int32_t size_vec, int3 fprintf( fp, "}" ); } +/*---------------------------------------------------------------------* + *write_array_word32_to_file(); + *---------------------------------------------------------------------*/ +void write_array_word32_to_file( FILE *fp, Word32 *vec, int32_t size_vec, int32_t sample_per_ligne, const int num_tab, const char *tab ) +{ + int32_t k, l, num_iter, remaining_samples; + int16_t i; + + num_iter = size_vec / sample_per_ligne; + remaining_samples = size_vec % sample_per_ligne; + if ( remaining_samples == 0 ) + { + num_iter--; + remaining_samples = sample_per_ligne; + } + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + + fprintf( fp, "{" ); + for ( k = 0; k < num_iter; k++ ) + { + if ( k != 0 ) + { + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + } + for ( l = 0; l < sample_per_ligne; l++ ) + { + fprintf( fp, "%d", vec[k * sample_per_ligne + l] ); + fprintf( fp, ", " ); + } + fprintf( fp, "\n" ); + } + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + for ( l = 0; l < remaining_samples - 1; l++ ) + { + fprintf( fp, "%d", vec[k * sample_per_ligne + l] ); + fprintf( fp, ", " ); + } + fprintf( fp, "%d", vec[k * sample_per_ligne + l] ); + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + fprintf( fp, "}" ); +} + +/*---------------------------------------------------------------------* + *write_array_word32_to_file(); + *---------------------------------------------------------------------*/ +void write_array_word16_to_file( FILE *fp, Word16 *vec, int32_t size_vec, int32_t sample_per_ligne, const int num_tab, const char *tab ) +{ + int32_t k, l, num_iter, remaining_samples; + int16_t i; + + num_iter = size_vec / sample_per_ligne; + remaining_samples = size_vec % sample_per_ligne; + if ( remaining_samples == 0 ) + { + num_iter--; + remaining_samples = sample_per_ligne; + } + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + + fprintf( fp, "{" ); + for ( k = 0; k < num_iter; k++ ) + { + if ( k != 0 ) + { + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + } + for ( l = 0; l < sample_per_ligne; l++ ) + { + fprintf( fp, "%d", vec[k * sample_per_ligne + l] ); + fprintf( fp, ", " ); + } + fprintf( fp, "\n" ); + } + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + for ( l = 0; l < remaining_samples - 1; l++ ) + { + fprintf( fp, "%d", vec[k * sample_per_ligne + l] ); + fprintf( fp, ", " ); + } + fprintf( fp, "%d", vec[k * sample_per_ligne + l] ); + for ( i = 0; i < num_tab; i++ ) + { + fprintf( fp, "%s", tab ); + } + fprintf( fp, "}" ); +} + /*---------------------------------------------------------------------* *update_c_file_with_reverb(); *---------------------------------------------------------------------*/ +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +void update_c_file_with_reverb( float *pEner_l, float *pEner_r, float *pCoherence, Word16 *pEner_l_fx, Word16 *pEner_r_fx, Word16 *pCoherence_fx, int16_t factorQ, const int32_t samplerate, const int16_t len ) +#else void update_c_file_with_reverb( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate, const int16_t len ) +#endif { char len_str[26] = "LR_IAC_LENGTH_NR_FC"; if ( samplerate == 16000 ) @@ -2026,17 +2223,17 @@ void update_c_file_with_reverb( float *pEner_l, float *pEner_r, float *pCoherenc /* float *defaultHRIR_right_avg_power_[LR_IAC_LENGTH_NR_FC];*/ fprintf( fp, "\nconst float defaultHRIR_coherence_%dkHz[%s] = \n", samplerate / 1000, len_str ); - write_array_float_to_file( fp, pCoherence, len, NUM_SAMPLES_PER_LINES_REVERB, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, pCoherence, len, NUM_SAMPLES_PER_LINES_REVERB, FORMAT_FLOAT_REVERB, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ";\n" ); /* float *defaultHRIR_left_avg_power_[LR_IAC_LENGTH_NR_FC];*/ fprintf( fp, "\nconst float defaultHRIR_left_avg_power_%dkHz[%s] = \n", samplerate / 1000, len_str ); - write_array_float_to_file( fp, pEner_l, len, NUM_SAMPLES_PER_LINES_REVERB, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, pEner_l, len, NUM_SAMPLES_PER_LINES_REVERB, FORMAT_FLOAT_REVERB, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ";\n" ); /* float *defaultHRIR_right_avg_power_[LR_IAC_LENGTH_NR_FC];*/ fprintf( fp, "\nconst float defaultHRIR_right_avg_power_%dkHz[%s] = \n", samplerate / 1000, len_str ); - write_array_float_to_file( fp, pEner_r, len, NUM_SAMPLES_PER_LINES_REVERB, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, pEner_r, len, NUM_SAMPLES_PER_LINES_REVERB, FORMAT_FLOAT_REVERB, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ";\n" ); if ( fp ) @@ -2047,7 +2244,11 @@ void update_c_file_with_reverb( float *pEner_l, float *pEner_r, float *pCoherenc /*---------------------------------------------------------------------* *update_c_file(); *---------------------------------------------------------------------*/ +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len, int16_t factorQ[3] ) +#else void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ) +#endif { if ( c_file_path == NULL ) @@ -2057,6 +2258,8 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int int16_t i, j; uint32_t *pTotalNumFreqSampPerIterations[2], maxTotalNumFreqSampPerIterations; uint32_t pTotalNumFreqSampPerIterationsDiffuse[2], maxTotalNumFreqSampPerIterationsDiffuse; + const char *format_float = FORMAT_FLOAT; + const char *format_float_latency = FORMAT_FLOAT_LATENCY; pTotalNumFreqSampPerIterations[0] = malloc( sizeof( float ) * hrtf->max_num_ir ); pTotalNumFreqSampPerIterations[1] = malloc( sizeof( float ) * hrtf->max_num_ir ); @@ -2070,7 +2273,9 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int { /* float latency_s; */ fprintf( fp, "\n\n/********************** %s_%s **********************/\n", DECLARATION_NAME, lscfg.name ); - fprintf( fp, "\nconst float %s_%s_latency_s = %10.9ff;", DECLARATION_NAME, lscfg.name, hrtf->latency_s ); + fprintf( fp, "\nconst float %s_%s_latency_s = ", DECLARATION_NAME, lscfg.name ); + fprintf( fp, format_float_latency, hrtf->latency_s ); + fprintf( fp, ";" ); } fprintf( fp, "\n\n/* Sample Rate = %ld */\n", (long) samplerate ); @@ -2155,9 +2360,9 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int /* float inv_diffuse_weight[BINAURAL_CHANNELS][MAX_INTERN_CHANNELS]; */ fprintf( fp, "\nconst float %s_%s_inv_diffuse_weight_%2dkHz[BINAURAL_CHANNELS][%s]=", DECLARATION_NAME, lscfg.name, samplerate / 1000, lscfg.output_config_num_channel_name ); fprintf( fp, "{" ); - write_array_float_to_file( fp, hrtf->inv_diffuse_weight[0], hrtf->max_num_ir, hrtf->max_num_ir, FORMAT_FLOAT, 0, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->inv_diffuse_weight[0], hrtf->max_num_ir, hrtf->max_num_ir, format_float, 0, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "," ); - write_array_float_to_file( fp, hrtf->inv_diffuse_weight[1], hrtf->max_num_ir, hrtf->max_num_ir, FORMAT_FLOAT, 0, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->inv_diffuse_weight[1], hrtf->max_num_ir, hrtf->max_num_ir, format_float, 0, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "}" ); fprintf( fp, ";" ); @@ -2180,15 +2385,15 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int for ( i = 0; i < hrtf->max_num_ir - 1; i++ ) { fprintf( fp, "\n%s{\n", TAB_WITH_SPACE_OR_NOT ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ",\n" ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n%s},", TAB_WITH_SPACE_OR_NOT ); } fprintf( fp, "\n%s{\n", TAB_WITH_SPACE_OR_NOT ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ",\n" ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_re[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n%s}", TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n};" ); @@ -2196,15 +2401,15 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int for ( i = 0; i < hrtf->max_num_ir - 1; i++ ) { fprintf( fp, "\n%s{\n", TAB_WITH_SPACE_OR_NOT ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ",\n" ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n%s},", TAB_WITH_SPACE_OR_NOT ); } fprintf( fp, "\n%s{\n", TAB_WITH_SPACE_OR_NOT ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][0], pTotalNumFreqSampPerIterations[0][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ",\n" ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_im[i][1], pTotalNumFreqSampPerIterations[1][i], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n%s}", TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n};" ); @@ -2216,9 +2421,9 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int else { fprintf( fp, "\nconst float %s_%s_coeff_diffuse_re_%2dkHz[BINAURAL_CHANNELS][%u]={", DECLARATION_NAME, lscfg.name, samplerate / 1000, maxTotalNumFreqSampPerIterationsDiffuse ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_re[0], pTotalNumFreqSampPerIterationsDiffuse[0], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_re[0], pTotalNumFreqSampPerIterationsDiffuse[0], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ",\n" ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_re[1], pTotalNumFreqSampPerIterationsDiffuse[1], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_re[1], pTotalNumFreqSampPerIterationsDiffuse[1], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n};" ); } @@ -2230,9 +2435,9 @@ void update_c_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int else { fprintf( fp, "\nconst float %s_%s_coeff_diffuse_im_%2dkHz[BINAURAL_CHANNELS][%u]={", DECLARATION_NAME, lscfg.name, samplerate / 1000, maxTotalNumFreqSampPerIterationsDiffuse ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_im[0], pTotalNumFreqSampPerIterationsDiffuse[0], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_im[0], pTotalNumFreqSampPerIterationsDiffuse[0], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, ",\n" ); - write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_im[1], pTotalNumFreqSampPerIterationsDiffuse[1], NUM_SAMPLES_PER_LINES, FORMAT_FLOAT, 2, TAB_WITH_SPACE_OR_NOT ); + write_array_float_to_file( fp, hrtf->pOut_to_bin_diffuse_im[1], pTotalNumFreqSampPerIterationsDiffuse[1], NUM_SAMPLES_PER_LINES, format_float, 2, TAB_WITH_SPACE_OR_NOT ); fprintf( fp, "\n};" ); } @@ -2378,6 +2583,7 @@ void update_h_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int /* float inv_diffuse_weight[BINAURAL_CHANNELS][MAX_INTERN_CHANNELS]; */ fprintf( fp, "\nextern float %s_%s_inv_diffuse_weight_%2dkHz[BINAURAL_CHANNELS][%s];", DECLARATION_NAME, lscfg.name, samplerate / 1000, lscfg.output_config_num_channel_name ); + /* uint16_t *pIndex_frequency_max_diffuse[BINAURAL_CHANNELS];*/ if ( hrtf->pIndex_frequency_max_diffuse[0] == NULL ) { @@ -2481,7 +2687,6 @@ void get_binary_tables_dimensions( HRTFS_DATA *hrtf, crend_hrtf_tables_dimension } } - /*---------------------------------------------------------------------* * compute_binary_size(); *---------------------------------------------------------------------*/ @@ -2511,10 +2716,14 @@ uint32_t compute_binary_size( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hr } } - hrtf_data_size += sizeof( uint16_t ); // index_frequency_max_diffuse + hrtf_data_size += sizeof( uint16_t ); // index_frequency_max_diffuse hrtf_data_size += hrtf->max_num_ir * sizeof( float ) * BINAURAL_CHANNELS; // inv_diffuse_weight +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration +#else hrtf_data_size += sizeof( uint16_t ); // max_total_num_fsamp_per_iteration +#endif // The sizes of coeff_re & coeff_im depend on pIndex_frequency_max for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) @@ -2528,7 +2737,11 @@ uint32_t compute_binary_size( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hr } } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration_diff +#else hrtf_data_size += sizeof( uint16_t ); // max_total_num_fsamp_per_iteration_diff +#endif if ( hrtf_table_dims->max_total_num_fsamp_per_iteration_diff != 0 ) { // The sizes of coeff_diffuse_re & coeff_diffuse_im depend on pIndex_frequency_max @@ -2544,83 +2757,725 @@ uint32_t compute_binary_size( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hr return hrtf_data_size; } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT /*---------------------------------------------------------------------* - * write_binary_file(); + * compute_binary_size_fx(); *---------------------------------------------------------------------*/ -void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ) +uint32_t compute_binary_size_fx( HRTFS_DATA *hrtf, crend_hrtf_tables_dimensions *hrtf_table_dims ) { - FILE *output_binary_file; + int16_t iIR, iIter, iChan; + uint32_t hrtf_data_size; - int16_t iIR, iIter, iChan, iTap; - uint32_t data_size_tmp; - float *coeff_rptr; - char tmpStr[64]; + hrtf_data_size = 0; - crend_hrtf_tables_dimensions hrtf_table_dims; + hrtf_data_size += sizeof( Word16 ); // latency_s Q factor + hrtf_data_size += sizeof( Word32 ); // latency_s + hrtf_data_size += sizeof( uint16_t ); // max_num_ir + hrtf_data_size += sizeof( uint16_t ); // BINAURAL_CHANNELS + hrtf_data_size += sizeof( int16_t ); // max_num_iterations + hrtf_data_size += hrtf->max_num_ir * BINAURAL_CHANNELS * sizeof( uint16_t ); // num_iterations + hrtf_data_size += hrtf->max_num_ir * BINAURAL_CHANNELS * hrtf->max_num_iterations * sizeof( uint16_t ); // pIndex_frequency_max - uint32_t hrtf_data_size; - char *hrtf_bin = NULL, *hrtf_bin_wptr; + hrtf_data_size += sizeof( int16_t ); // max_num_iterations_diffuse - char *binary_file_full_path = NULL; + if ( hrtf_table_dims->max_num_iterations_diffuse != 0 ) + { + hrtf_data_size += BINAURAL_CHANNELS * sizeof( uint16_t ); // num_iterations_diffuse + // The size of pIndex_frequency_max_diffuse depends on num_iterations_diffuse + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + hrtf_data_size += hrtf->num_iterations_diffuse[iChan] * sizeof( uint16_t ); + } + } - if ( hrtf == NULL ) - return; + hrtf_data_size += sizeof( uint16_t ); // index_frequency_max_diffuse - if ( binary_file_path == NULL ) - return; + hrtf_data_size += sizeof( Word16 ); // Q factor inv_diffuse_weight - /* Binary file - block description : + hrtf_data_size += hrtf->max_num_ir * sizeof( Word16 ) * BINAURAL_CHANNELS; // inv_diffuse_weight - latency_s => float + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration - max_num_ir => uint16_t - BINAURAL_CHANNELS => uint16_t (BINAURAL_CHANNELS) + hrtf_data_size += sizeof( Word16 ); // Q factor + // The sizes of coeff_re & coeff_im depend on pIndex_frequency_max + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + hrtf_data_size += 2 * hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( Word32 ); // 2* : re & im + } + } + } - max_num_iterations => int16_t - num_iterations => uint16_t[max_num_ir][BINAURAL_CHANNELS] - pIndex_frequency_max => uint16_t[max_num_ir][BINAURAL_CHANNELS][max_num_iterations] (Pointer) + hrtf_data_size += sizeof( uint32_t ); // max_total_num_fsamp_per_iteration_diff + if ( hrtf_table_dims->max_total_num_fsamp_per_iteration_diff != 0 ) + { + // The sizes of coeff_diffuse_re & coeff_diffuse_im depend on pIndex_frequency_max + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + hrtf_data_size += 2 * hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( Word32 ); // 2* : re & im + } + } + } - max_num_iterations_diffuse => int16_t - num_iterations_diffuse => uint16_t[BINAURAL_CHANNELS] - pIndex_frequency_max_diffuse => uint16_t[BINAURAL_CHANNELS][max_num_iterations_diffuse] (Pointer) + return hrtf_data_size; +} - index_frequency_max_diffuse => uint16_t - inv_diffuse_weight => float[max_num_ir] - max_total_num_fsamp_per_iteration => uint16_t - coeff_re => float[max_num_ir][BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) - coeff_im => float[max_num_ir][BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) +/*---------------------------------------------------------------------* + * make_fx_be(); + *---------------------------------------------------------------------*/ +ivas_error make_fx_be( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len, int16_t factorQ[3] ) +{ + FILE *output_binary_file; - max_total_num_fsamp_per_iteration_diff => uint16_t - coeff_diffuse_re => float[BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) - coeff_diffuse_im => float[BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) - */ + int16_t iIR, iIter, iChan, iTap; + uint32_t data_size_tmp; + float *coeff_rptr; + float maxVal; + char tmpStr[64]; + float maxDiff = 0, diff, tmp, tmp2; + Word16 tmp16; + Word32 tmp32; + + crend_hrtf_tables_dimensions hrtf_table_dims; + + if ( hrtf == NULL ) + return IVAS_ERR_FAILED_ALLOC; get_binary_tables_dimensions( hrtf, &hrtf_table_dims ); - hrtf_data_size = compute_binary_size( hrtf, &hrtf_table_dims ); + // Write the HRTF raw data - hrtf_bin = NULL; - hrtf_bin = (char *) malloc( hrtf_data_size ); - if ( hrtf_bin == NULL ) - return; + maxDiff = 0; + + if ( hrtf->latency_s > 0 ) + { + factorQ[0] = (Word16) floorf( 31.f - logf( hrtf->latency_s ) / logf( 2.f ) ); + } + else + { + factorQ[0] = 0; + } + + tmp = hrtf->latency_s; + tmp32 = float2Word32( hrtf->latency_s, factorQ[0] ); + hrtf->latency_s = (float) tmp32 * powf( 2.f, -1.f * (float) factorQ[0] ); + maxDiff = fabsf( hrtf->latency_s - tmp ); + + maxVal = 0; + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + if ( maxVal < fabsf( hrtf->inv_diffuse_weight[0][iIR] ) ) + { + maxVal = fabsf( hrtf->inv_diffuse_weight[0][iIR] ); + } + if ( maxVal < fabsf( hrtf->inv_diffuse_weight[1][iIR] ) ) + { + maxVal = fabsf( hrtf->inv_diffuse_weight[1][iIR] ); + } + } + + if ( maxVal > 0 ) + { + factorQ[1] = (Word16) floorf( 15.f - logf( maxVal ) / logf( 2.f ) ); + } + else + { + factorQ[1] = 0; + } + + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + tmp = hrtf->inv_diffuse_weight[0][iIR]; + tmp16 = float2Word16( hrtf->inv_diffuse_weight[0][iIR], factorQ[1] ); + hrtf->inv_diffuse_weight[0][iIR] = (float) tmp16 * powf( 2.f, -1.f * factorQ[1] ); + diff = fabsf( hrtf->inv_diffuse_weight[0][iIR] - tmp ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + tmp = hrtf->inv_diffuse_weight[1][iIR]; + tmp16 = float2Word16( hrtf->inv_diffuse_weight[1][iIR], factorQ[1] ); + hrtf->inv_diffuse_weight[1][iIR] = (float) tmp16 * powf( 2.f, -1.f * factorQ[1] ); + diff = fabsf( hrtf->inv_diffuse_weight[1][iIR] - tmp ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + + // find max values + maxVal = 0; + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_re[iIR][iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) + { + if ( maxVal < fabsf( coeff_rptr[iTap] ) ) + { + maxVal = fabsf( coeff_rptr[iTap] ); + } + } + coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; + } + } + } + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_im[iIR][iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) + { + if ( maxVal < fabsf( coeff_rptr[iTap] ) ) + { + maxVal = fabsf( coeff_rptr[iTap] ); + } + } + coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; + } + } + } + + if ( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff != 0 ) + { + // find max value + + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_diffuse_re[iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) + { + if ( maxVal < fabsf( coeff_rptr[iTap] ) ) + { + maxVal = fabsf( coeff_rptr[iTap] ); + } + } + coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; + } + } + + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_diffuse_im[iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) + { + if ( maxVal < fabsf( coeff_rptr[iTap] ) ) + { + maxVal = fabsf( coeff_rptr[iTap] ); + } + } + coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; + } + } + } + + if ( maxVal > 0 ) + { + factorQ[2] = (Word16) floorf( 31.f - logf( maxVal ) / logf( 2.f ) ); + } + else + { + factorQ[2] = 0; + } + + // pOut_to_bin_re (The size depends on pIndex_frequency_max) + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_re[iIR][iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + tmp32 = float2Word32( coeff_rptr[iTap], factorQ[2] ); + coeff_rptr[iTap] = (float) tmp32 * powf( 2.f, -1.f * (float) factorQ[2] ); + diff = fabsf( tmp - coeff_rptr[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; + } + } + } + + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_im[iIR][iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + tmp32 = float2Word32( coeff_rptr[iTap], factorQ[2] ); + coeff_rptr[iTap] = (float) tmp32 * powf( 2.f, -1.f * (float) factorQ[2] ); + diff = fabsf( tmp - coeff_rptr[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; + } + } + } + + + if ( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff != 0 ) + { + // pOut_to_bin_diffuse_re : The size depends on pIndex_frequency_max_diffuse + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_diffuse_re[iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + tmp32 = float2Word32( coeff_rptr[iTap], factorQ[2] ); + coeff_rptr[iTap] = (float) tmp32 * powf( 2.f, -1.f * factorQ[2] ); + diff = fabsf( tmp - coeff_rptr[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; + } + } + + // pOut_to_bin_diffuse_im : The size depends on pIndex_frequency_max_diffuse + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_diffuse_im[iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( float ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + tmp32 = float2Word32( coeff_rptr[iTap], factorQ[2] ); + coeff_rptr[iTap] = (float) tmp32 * powf( 2.f, -1.f * factorQ[2] ); + diff = fabsf( tmp - coeff_rptr[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; + } + } + } + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * write_binary_file_fx(); + *---------------------------------------------------------------------*/ +ivas_error write_binary_file_fx( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len, int16_t factorQ[3] ) +{ + FILE *output_binary_file; + + int16_t iIR, iIter, iChan, iTap; + uint32_t data_size_tmp; + float *coeff_rptr; + float maxVal; + + char tmpStr[64]; + float maxDiff = 0, diff, tmp, tmp2; + + crend_hrtf_tables_dimensions hrtf_table_dims; + + uint32_t hrtf_data_size; + char *hrtf_bin = NULL, *hrtf_bin_wptr; + + char *binary_file_full_path = NULL; + + if ( hrtf == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + if ( binary_file_path == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + /* Binary file - block description : + + latency_s Q scaling factor => Wor16 + latency_s => Word32 + + max_num_ir => uint16_t + BINAURAL_CHANNELS => uint16_t (BINAURAL_CHANNELS) + + max_num_iterations => int16_t + num_iterations => uint16_t[max_num_ir][BINAURAL_CHANNELS] + pIndex_frequency_max => uint16_t[max_num_ir][BINAURAL_CHANNELS][max_num_iterations] (Pointer) + + max_num_iterations_diffuse => int16_t + num_iterations_diffuse => uint16_t[BINAURAL_CHANNELS] + pIndex_frequency_max_diffuse => uint16_t[BINAURAL_CHANNELS][max_num_iterations_diffuse] (Pointer) + + index_frequency_max_diffuse => uint16_t + inv_diffuse_weight Q scaling factor => Wor16 + inv_diffuse_weight => Word16[BINAURAL_CHANNELS][max_num_ir] + + max_total_num_fsamp_per_iteration => uint32_t + coeff Q scaling factor => Wor16 + coeff_re => Word32[max_num_ir][BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + coeff_im => Word32[max_num_ir][BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + + max_total_num_fsamp_per_iteration_diff => uint32_t + coeff_diffuse_re => Word32[BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + coeff_diffuse_im => Word32[BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + */ + + get_binary_tables_dimensions( hrtf, &hrtf_table_dims ); + + hrtf_data_size = compute_binary_size_fx( hrtf, &hrtf_table_dims ); + + hrtf_bin = NULL; + hrtf_bin = (char *) malloc( hrtf_data_size ); + if ( hrtf_bin == NULL ) + return IVAS_ERR_FAILED_ALLOC; + memset( hrtf_bin, 0x00, hrtf_data_size ); + hrtf_bin_wptr = hrtf_bin; + + // Write the HRTF raw data + ( (Word16 *) hrtf_bin_wptr )[0] = factorQ[0]; // factor Q for latency + hrtf_bin_wptr += sizeof( Word16 ); + + maxDiff = 0; + tmp = hrtf->latency_s; + ( (Word32 *) hrtf_bin_wptr )[0] = float2Word32( tmp, factorQ[0] ); + maxDiff = fabsf( tmp - (float) ( (Word32 *) hrtf_bin_wptr )[0] * powf( 2.f, -1.f * (float) factorQ[0] ) ); + hrtf_bin_wptr += sizeof( Word32 ); + + ( (uint16_t *) hrtf_bin_wptr )[0] = hrtf->max_num_ir; + hrtf_bin_wptr += sizeof( uint16_t ); + + ( (uint16_t *) hrtf_bin_wptr )[0] = BINAURAL_CHANNELS; + hrtf_bin_wptr += sizeof( uint16_t ); + + ( (int16_t *) hrtf_bin_wptr )[0] = hrtf->max_num_iterations; // max_num_iterations + hrtf_bin_wptr += sizeof( int16_t ); + + data_size_tmp = hrtf->max_num_ir * BINAURAL_CHANNELS * sizeof( uint16_t ); + memcpy( hrtf_bin_wptr, hrtf->num_iterations, data_size_tmp ); // num_iterations + hrtf_bin_wptr += data_size_tmp; + + // pIndex_frequency_max + data_size_tmp = hrtf->max_num_iterations * sizeof( uint16_t ); + for ( int iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + memcpy( hrtf_bin_wptr, hrtf->pIndex_frequency_max[iIR][iChan], data_size_tmp ); + hrtf_bin_wptr += data_size_tmp; + } + } + + memcpy( hrtf_bin_wptr, &( hrtf_table_dims.max_num_iterations_diffuse ), sizeof( int16_t ) ); // max_num_iterations_diffuse + hrtf_bin_wptr += sizeof( int16_t ); + + if ( hrtf_table_dims.max_num_iterations_diffuse != 0 ) + { + data_size_tmp = BINAURAL_CHANNELS * sizeof( uint16_t ); + memcpy( hrtf_bin_wptr, hrtf->num_iterations_diffuse, data_size_tmp ); // num_iterations_diffuse + hrtf_bin_wptr += data_size_tmp; + + // pIndex_frequency_max_diffuse (the size depends on num_iterations_diffuse) + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + data_size_tmp = hrtf->num_iterations_diffuse[iChan] * sizeof( uint16_t ); + memcpy( hrtf_bin_wptr, hrtf->pIndex_frequency_max_diffuse[iChan], data_size_tmp ); + hrtf_bin_wptr += data_size_tmp; + } + } + + ( (Word16 *) hrtf_bin_wptr )[0] = hrtf->index_frequency_max_diffuse; // index_frequency_max_diffuse + hrtf_bin_wptr += sizeof( uint16_t ); + + ( (Word16 *) hrtf_bin_wptr )[0] = factorQ[1]; // Q factor for filters + hrtf_bin_wptr += sizeof( Word16 ); + + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + tmp = hrtf->inv_diffuse_weight[0][iIR]; + ( (Word16 *) hrtf_bin_wptr )[iIR] = float2Word16( hrtf->inv_diffuse_weight[0][iIR], factorQ[1] ); + diff = fabsf( tmp - (float) ( (Word16 *) hrtf_bin_wptr )[iIR] * powf( 2.f, -1.f * factorQ[1] ) ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + + data_size_tmp = hrtf->max_num_ir * sizeof( Word16 ); + hrtf_bin_wptr += data_size_tmp; + + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + tmp = hrtf->inv_diffuse_weight[1][iIR]; + ( (Word16 *) hrtf_bin_wptr )[iIR] = float2Word16( hrtf->inv_diffuse_weight[1][iIR], factorQ[1] ); + diff = fabsf( tmp - (float) ( (Word16 *) hrtf_bin_wptr )[iIR] * powf( 2.f, -1.f * factorQ[1] ) ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + data_size_tmp = hrtf->max_num_ir * sizeof( Word16 ); + hrtf_bin_wptr += data_size_tmp; + + ( (uint32_t *) hrtf_bin_wptr )[0] = hrtf_table_dims.max_total_num_fsamp_per_iteration; // max_total_num_fsamp_per_iteration + hrtf_bin_wptr += sizeof( uint32_t ); + + ( (Word16 *) hrtf_bin_wptr )[0] = factorQ[2]; // Q factor for filters + hrtf_bin_wptr += sizeof( Word16 ); + + // pOut_to_bin_re (The size depends on pIndex_frequency_max) + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_re[iIR][iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( Word32 ); + // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + ( (Word32 *) hrtf_bin_wptr )[iTap] = float2Word32( coeff_rptr[iTap], factorQ[2] ); + tmp2 = ( (float) ( ( (Word32 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ[2] ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += data_size_tmp; + coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; + } + } + } + + // pOut_to_bin_im (The size depends on pIndex_frequency_max) + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) + { + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_im[iIR][iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( Word32 ); + + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + ( (Word32 *) hrtf_bin_wptr )[iTap] = float2Word32( coeff_rptr[iTap], factorQ[2] ); + tmp2 = ( (float) ( ( (Word32 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ[2] ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += data_size_tmp; + coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; + } + } + } + + memcpy( hrtf_bin_wptr, &( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff ), sizeof( uint32_t ) ); // max_total_num_fsamp_per_iteration_diff + hrtf_bin_wptr += sizeof( uint32_t ); + + if ( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff != 0 ) + { + // pOut_to_bin_diffuse_re : The size depends on pIndex_frequency_max_diffuse + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_diffuse_re[iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( Word32 ); + + // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + ( (Word32 *) hrtf_bin_wptr )[iTap] = float2Word32( coeff_rptr[iTap], factorQ[2] ); + tmp2 = ( (float) ( ( (Word32 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ[2] ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += data_size_tmp; + coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; + } + } + + // pOut_to_bin_diffuse_im : The size depends on pIndex_frequency_max_diffuse + for ( iChan = 0; iChan < BINAURAL_CHANNELS; iChan++ ) + { + coeff_rptr = hrtf->pOut_to_bin_diffuse_im[iChan]; + for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) + { + data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( Word32 ); + // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); + for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) + { + tmp = coeff_rptr[iTap]; + ( (Word32 *) hrtf_bin_wptr )[iTap] = float2Word32( coeff_rptr[iTap], factorQ[2] ); + tmp2 = ( (float) ( ( (Word32 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ[2] ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += data_size_tmp; + coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; + } + } + } + + if ( hrtf_bin_wptr - hrtf_bin != hrtf_data_size ) + { + free( hrtf_bin ); + return IVAS_ERR_FAILED_FILE_WRITE; + } + + binary_file_full_path = (char *) malloc( sizeof( char ) * ( strlen( binary_file_path ) + 1 + strlen( lscfg.name ) + 1 + 5 + 3 + 4 + 3 ) ); + sprintf( binary_file_full_path, "%s_%s_%ikHz_fx.bin", binary_file_path, lscfg.name, samplerate / 1000 ); + fprintf( stdout, "Write Binary file %s:\n", binary_file_full_path ); + + output_binary_file = fopen( binary_file_full_path, "wb" ); + if ( output_binary_file == NULL ) + { + free( hrtf_bin ); + return IVAS_ERR_FAILED_FILE_WRITE; + } + fwrite( hrtf_bin, hrtf_data_size, 1, output_binary_file ); + fclose( output_binary_file ); + + free( hrtf_bin ); + free( binary_file_full_path ); + return IVAS_ERR_OK; +} +#endif + +/*---------------------------------------------------------------------* + * write_binary_file(); + *---------------------------------------------------------------------*/ +ivas_error write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const int32_t samplerate, const int16_t frame_len ) +{ + FILE *output_binary_file; + + int16_t iIR, iIter, iChan, iTap; + uint32_t data_size_tmp; + float *coeff_rptr; + char tmpStr[64]; + + crend_hrtf_tables_dimensions hrtf_table_dims; + + uint32_t hrtf_data_size; + char *hrtf_bin = NULL, *hrtf_bin_wptr; + + char *binary_file_full_path = NULL; + + if ( hrtf == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + if ( binary_file_path == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + /* Binary file - block description : + + latency_s => float + + max_num_ir => uint16_t + BINAURAL_CHANNELS => uint16_t (BINAURAL_CHANNELS) + + max_num_iterations => int16_t + num_iterations => uint16_t[max_num_ir][BINAURAL_CHANNELS] + pIndex_frequency_max => uint16_t[max_num_ir][BINAURAL_CHANNELS][max_num_iterations] (Pointer) + + max_num_iterations_diffuse => int16_t + num_iterations_diffuse => uint16_t[BINAURAL_CHANNELS] + pIndex_frequency_max_diffuse => uint16_t[BINAURAL_CHANNELS][max_num_iterations_diffuse] (Pointer) + + index_frequency_max_diffuse => uint16_t + inv_diffuse_weight => float[BINAURAL_CHANNELS][max_num_ir] + +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + max_total_num_fsamp_per_iteration => uint32_t +#else + max_total_num_fsamp_per_iteration => uint16_t +#endif + coeff_re => float[max_num_ir][BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + coeff_im => float[max_num_ir][BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + max_total_num_fsamp_per_iteration_diff => uint32_t +#else + max_total_num_fsamp_per_iteration_diff => uint16_t +#endif + coeff_diffuse_re => float[BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + coeff_diffuse_im => float[BINAURAL_CHANNELS][max_total_num_fsamp_per_iteration] (Pointer) + */ + + get_binary_tables_dimensions( hrtf, &hrtf_table_dims ); + + hrtf_data_size = compute_binary_size( hrtf, &hrtf_table_dims ); + + hrtf_bin = NULL; + hrtf_bin = (char *) malloc( hrtf_data_size ); + if ( hrtf_bin == NULL ) + return IVAS_ERR_FAILED_ALLOC; memset( hrtf_bin, 0x00, hrtf_data_size ); hrtf_bin_wptr = hrtf_bin; // Write the HRTF raw data - memcpy( hrtf_bin_wptr, &( hrtf->latency_s ), sizeof( float ) ); // latency_s + ( (float *) hrtf_bin_wptr )[0] = hrtf->latency_s; hrtf_bin_wptr += sizeof( float ); - memcpy( hrtf_bin_wptr, &( hrtf->max_num_ir ), sizeof( uint16_t ) ); // max_num_ir + ( (uint16_t *) hrtf_bin_wptr )[0] = hrtf->max_num_ir; hrtf_bin_wptr += sizeof( uint16_t ); - uint16_t nchan_bin = BINAURAL_CHANNELS; - memcpy( hrtf_bin_wptr, &nchan_bin, sizeof( uint16_t ) ); // BINAURAL_CHANNELS + ( (uint16_t *) hrtf_bin_wptr )[0] = BINAURAL_CHANNELS; hrtf_bin_wptr += sizeof( uint16_t ); - memcpy( hrtf_bin_wptr, &( hrtf->max_num_iterations ), sizeof( int16_t ) ); // max_num_iterations + + ( (int16_t *) hrtf_bin_wptr )[0] = hrtf->max_num_iterations; // max_num_iterations hrtf_bin_wptr += sizeof( int16_t ); data_size_tmp = hrtf->max_num_ir * BINAURAL_CHANNELS * sizeof( uint16_t ); @@ -2661,19 +3516,38 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iIR] = hrtf->inv_diffuse_weight[0][iIR]; +#else sprintf( tmpStr, FORMAT_FLOAT, hrtf->inv_diffuse_weight[0][iIR] ); sscanf( tmpStr, "%f", &( (float *) hrtf_bin_wptr )[iIR] ); +#endif } + + data_size_tmp = hrtf->max_num_ir * sizeof( float ); + hrtf_bin_wptr += data_size_tmp; + for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iIR] = hrtf->inv_diffuse_weight[1][iIR]; +#else sprintf( tmpStr, FORMAT_FLOAT, hrtf->inv_diffuse_weight[1][iIR] ); - sscanf( tmpStr, "%f", &( (float *) hrtf_bin_wptr )[hrtf->max_num_ir + iIR] ); + sscanf( tmpStr, "%f", &( (float *) hrtf_bin_wptr )[iIR] ); +#endif } - data_size_tmp = hrtf->max_num_ir * sizeof( float ) * BINAURAL_CHANNELS; + data_size_tmp = hrtf->max_num_ir * sizeof( float ); hrtf_bin_wptr += data_size_tmp; + +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + memcpy( hrtf_bin_wptr, &( hrtf_table_dims.max_total_num_fsamp_per_iteration ), sizeof( uint32_t ) ); // max_total_num_fsamp_per_iteration + hrtf_bin_wptr += sizeof( uint32_t ); +#else memcpy( hrtf_bin_wptr, &( hrtf_table_dims.max_total_num_fsamp_per_iteration ), sizeof( uint16_t ) ); // max_total_num_fsamp_per_iteration hrtf_bin_wptr += sizeof( uint16_t ); +#endif + // pOut_to_bin_re (The size depends on pIndex_frequency_max) for ( iIR = 0; iIR < hrtf->max_num_ir; iIR++ ) @@ -2687,9 +3561,13 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; +#else //( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; sprintf( tmpStr, FORMAT_FLOAT, coeff_rptr[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += data_size_tmp; coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; @@ -2706,12 +3584,15 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const for ( iIter = 0; iIter < hrtf->num_iterations[iIR][iChan]; iIter++ ) { data_size_tmp = hrtf->pIndex_frequency_max[iIR][iChan][iIter] * sizeof( float ); - // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); for ( iTap = 0; iTap < hrtf->pIndex_frequency_max[iIR][iChan][iIter]; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; +#else //( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; sprintf( tmpStr, FORMAT_FLOAT, coeff_rptr[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += data_size_tmp; coeff_rptr += hrtf->pIndex_frequency_max[iIR][iChan][iIter]; @@ -2719,8 +3600,13 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const } } +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + memcpy( hrtf_bin_wptr, &( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff ), sizeof( uint32_t ) ); // max_total_num_fsamp_per_iteration_diff + hrtf_bin_wptr += sizeof( uint32_t ); +#else memcpy( hrtf_bin_wptr, &( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff ), sizeof( uint16_t ) ); // max_total_num_fsamp_per_iteration_diff hrtf_bin_wptr += sizeof( uint16_t ); +#endif if ( hrtf_table_dims.max_total_num_fsamp_per_iteration_diff != 0 ) { @@ -2731,12 +3617,15 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) { data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( float ); - // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; +#else //( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; sprintf( tmpStr, FORMAT_FLOAT, coeff_rptr[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += data_size_tmp; coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; @@ -2750,12 +3639,15 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const for ( iIter = 0; iIter < hrtf->num_iterations_diffuse[iChan]; iIter++ ) { data_size_tmp = hrtf->pIndex_frequency_max_diffuse[iChan][iIter] * sizeof( float ); - // memcpy( hrtf_bin_wptr, coeff_rptr, data_size_tmp ); for ( iTap = 0; iTap < hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; +#else //( (float *) hrtf_bin_wptr )[iTap] = coeff_rptr[iTap]; sprintf( tmpStr, FORMAT_FLOAT, coeff_rptr[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += data_size_tmp; coeff_rptr += hrtf->pIndex_frequency_max_diffuse[iChan][iIter]; @@ -2763,6 +3655,12 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const } } + if ( hrtf_bin_wptr - hrtf_bin != hrtf_data_size ) + { + free( hrtf_bin ); + return IVAS_ERR_FAILED_FILE_WRITE; + } + binary_file_full_path = (char *) malloc( sizeof( char ) * ( strlen( binary_file_path ) + 1 + strlen( lscfg.name ) + 1 + 5 + 3 + 4 ) ); sprintf( binary_file_full_path, "%s_%s_%ikHz.bin", binary_file_path, lscfg.name, samplerate / 1000 ); fprintf( stdout, "Write Binary file %s:\n", binary_file_full_path ); @@ -2771,74 +3669,302 @@ void write_binary_file( HRTFS_DATA *hrtf, struct ivas_layout_config lscfg, const if ( output_binary_file == NULL ) { free( hrtf_bin ); - return; + return IVAS_ERR_FAILED_FILE_WRITE; + } + fwrite( hrtf_bin, hrtf_data_size, 1, output_binary_file ); + fclose( output_binary_file ); + + free( hrtf_bin ); + free( binary_file_full_path ); + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * make_fx_be(); + *---------------------------------------------------------------------*/ +ivas_error make_reverb_fx_be( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate, Word16 *factorQ ) +{ + FILE *output_binary_file; + uint32_t hrtf_data_size; + + + int16_t iTap; + float *coeff_rptr; + float maxVal; + char tmpStr[64]; + float maxDiff = 0, diff, tmp, tmp2; + Word16 tmp16; + + int16_t len = LR_IAC_LENGTH_NR_FC; + if ( samplerate == 16000 ) + { + len = LR_IAC_LENGTH_NR_FC_16KHZ; + } + + if ( pEner_l == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + if ( pEner_r == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + if ( pCoherence == NULL ) + return IVAS_ERR_FAILED_ALLOC; + + maxVal = 0; + for ( iTap = 0; iTap < len; iTap++ ) + { + if ( maxVal < fabsf( pEner_l[iTap] ) ) + { + maxVal = fabsf( pEner_l[iTap] ); + } + if ( maxVal < fabsf( pEner_r[iTap] ) ) + { + maxVal = fabsf( pEner_r[iTap] ); + } + if ( maxVal < fabsf( pCoherence[iTap] ) ) + { + maxVal = fabsf( pCoherence[iTap] ); + } + } + + if ( maxVal > 0 ) + { + factorQ[0] = (Word16) floorf( 15.f - logf( maxVal ) / logf( 2.f ) ); + } + else + { + factorQ[0] = 0; + } + + for ( iTap = 0; iTap < len; iTap++ ) + { + tmp = pEner_l[iTap]; + tmp16 = float2Word16( pEner_l[iTap], factorQ[0] ); + pEner_l[iTap] = (float) tmp16 * powf( 2.f, -1.f * (float) factorQ[0] ); + diff = fabsf( tmp - pEner_l[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + for ( iTap = 0; iTap < len; iTap++ ) + { + tmp = pEner_r[iTap]; + tmp16 = float2Word16( pEner_r[iTap], factorQ[0] ); + pEner_r[iTap] = (float) tmp16 * powf( 2.f, -1.f * (float) factorQ[0] ); + diff = fabsf( tmp - pEner_r[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + for ( iTap = 0; iTap < len; iTap++ ) + { + tmp = pCoherence[iTap]; + tmp16 = float2Word16( pCoherence[iTap], factorQ[0] ); + pCoherence[iTap] = (float) tmp16 * powf( 2.f, -1.f * (float) factorQ[0] ); + diff = fabsf( tmp - pCoherence[iTap] ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + return IVAS_ERR_OK; +} + +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT +/*---------------------------------------------------------------------* + * write_binary_file_fx(); + *---------------------------------------------------------------------*/ +ivas_error write_reverb_to_binary_file_fx( float *pEner_l, float *pEner_r, float *pCoherence, Word16 factorQ, const int32_t samplerate ) +{ + FILE *output_binary_file; + + int16_t iTap; + char tmpStr[64]; + uint32_t hrtf_data_size; + float maxDiff = 0, diff, tmp, tmp2; + Word16 tmp16; + + char *hrtf_bin = NULL, *hrtf_bin_wptr; + + char *binary_file_full_path = NULL; + + int16_t len = LR_IAC_LENGTH_NR_FC; + + if ( samplerate == 16000 ) + { + len = LR_IAC_LENGTH_NR_FC_16KHZ; + } + + if ( pEner_l == NULL ) + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + ; + + if ( pEner_r == NULL ) + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + + if ( pCoherence == NULL ) + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + + if ( binary_file_path == NULL ) + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + + hrtf_bin = NULL; + hrtf_data_size = sizeof( Word16 ) * 3 * len + sizeof( Word16 ); + hrtf_bin = (char *) malloc( hrtf_data_size ); + if ( hrtf_bin == NULL ) + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + memset( hrtf_bin, 0x00, hrtf_data_size ); + hrtf_bin_wptr = hrtf_bin; + + memcpy( hrtf_bin_wptr, &factorQ, sizeof( Word16 ) ); // Q factor for filters + hrtf_bin_wptr += sizeof( Word16 ); + + for ( iTap = 0; iTap < len; iTap++ ) + { + tmp = pEner_l[iTap]; + ( (Word16 *) hrtf_bin_wptr )[iTap] = float2Word16( pEner_l[iTap], factorQ ); + tmp2 = ( (float) ( ( (Word16 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += sizeof( Word16 ) * len; + for ( iTap = 0; iTap < len; iTap++ ) + { + tmp = pEner_r[iTap]; + ( (Word16 *) hrtf_bin_wptr )[iTap] = float2Word16( pEner_r[iTap], factorQ ); + tmp2 = ( (float) ( ( (Word16 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += sizeof( Word16 ) * len; + for ( iTap = 0; iTap < len; iTap++ ) + { + tmp = pCoherence[iTap]; + ( (Word16 *) hrtf_bin_wptr )[iTap] = float2Word16( pCoherence[iTap], factorQ ); + tmp2 = ( (float) ( ( (Word16 *) hrtf_bin_wptr )[iTap] ) ) * powf( 2.f, -1.f * (float) factorQ ); + diff = fabsf( tmp - tmp2 ); + if ( maxDiff < diff ) + { + maxDiff = diff; + } + } + hrtf_bin_wptr += sizeof( Word16 ) * len; + + if ( hrtf_bin_wptr - hrtf_bin != hrtf_data_size ) + { + free( hrtf_bin ); + return IVAS_ERR_FAILED_FILE_WRITE; + } + + binary_file_full_path = (char *) malloc( sizeof( char ) * ( strlen( binary_file_path ) + 1 + strlen( "Reverb" ) + 1 + 5 + 3 + 4 ) ); + sprintf( binary_file_full_path, "%s_%s_%ikHz_fx.bin", binary_file_path, "Reverb", samplerate / 1000 ); + fprintf( stdout, "Write Binary file %s:\n", binary_file_full_path ); + + output_binary_file = fopen( binary_file_full_path, "wb" ); + if ( output_binary_file == NULL ) + { + free( hrtf_bin ); + return IVAS_ERR_FAILED_FILE_WRITE; } fwrite( hrtf_bin, hrtf_data_size, 1, output_binary_file ); fclose( output_binary_file ); free( hrtf_bin ); free( binary_file_full_path ); + + return IVAS_ERR_OK; } + +#endif /*---------------------------------------------------------------------* * write_binary_file(); *---------------------------------------------------------------------*/ -void write_reverb_to_binary_file( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate ) +ivas_error write_reverb_to_binary_file( float *pEner_l, float *pEner_r, float *pCoherence, const int32_t samplerate ) { FILE *output_binary_file; int16_t iTap; char tmpStr[64]; uint32_t hrtf_data_size; + float maxVal; char *hrtf_bin = NULL, *hrtf_bin_wptr; char *binary_file_full_path = NULL; int16_t len = LR_IAC_LENGTH_NR_FC; + if ( samplerate == 16000 ) { len = LR_IAC_LENGTH_NR_FC_16KHZ; } if ( pEner_l == NULL ) - return; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; if ( pEner_r == NULL ) - return; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; if ( pCoherence == NULL ) - return; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; if ( binary_file_path == NULL ) - return; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; hrtf_bin = NULL; hrtf_data_size = sizeof( float ) * 3 * len; hrtf_bin = (char *) malloc( hrtf_data_size ); if ( hrtf_bin == NULL ) - return; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; memset( hrtf_bin, 0x00, hrtf_data_size ); hrtf_bin_wptr = hrtf_bin; for ( iTap = 0; iTap < len; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = pEner_l[iTap]; +#else sprintf( tmpStr, FORMAT_FLOAT, pEner_l[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += sizeof( float ) * len; for ( iTap = 0; iTap < len; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = pEner_r[iTap]; +#else sprintf( tmpStr, FORMAT_FLOAT, pEner_r[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += sizeof( float ) * len; for ( iTap = 0; iTap < len; iTap++ ) { +#ifdef FIX_CREND_FIX_POINT_HRTF_FILE_FORMAT + ( (float *) hrtf_bin_wptr )[iTap] = pCoherence[iTap]; +#else sprintf( tmpStr, FORMAT_FLOAT, pCoherence[iTap] ); sscanf( tmpStr, "%f", &( ( (float *) hrtf_bin_wptr )[iTap] ) ); +#endif } hrtf_bin_wptr += sizeof( float ) * len; + if ( hrtf_bin_wptr - hrtf_bin != hrtf_data_size ) + { + free( hrtf_bin ); + return IVAS_ERR_FAILED_FILE_WRITE; + } + binary_file_full_path = (char *) malloc( sizeof( char ) * ( strlen( binary_file_path ) + 1 + strlen( "Reverb" ) + 1 + 5 + 3 + 4 ) ); sprintf( binary_file_full_path, "%s_%s_%ikHz.bin", binary_file_path, "Reverb", samplerate / 1000 ); fprintf( stdout, "Write Binary file %s:\n", binary_file_full_path ); @@ -2847,13 +3973,15 @@ void write_reverb_to_binary_file( float *pEner_l, float *pEner_r, float *pCohere if ( output_binary_file == NULL ) { free( hrtf_bin ); - return; + return IVAS_ERR_FAILED_FILE_WRITE; } fwrite( hrtf_bin, hrtf_data_size, 1, output_binary_file ); fclose( output_binary_file ); free( hrtf_bin ); free( binary_file_full_path ); + + return IVAS_ERR_OK; } /*---------------------------------------------------------------------* diff --git a/scripts/binauralRenderer_interface/generate_ivas_binauralizer_tables_from_sofa.m b/scripts/binauralRenderer_interface/generate_ivas_binauralizer_tables_from_sofa.m index 491062b1aa6a9c6d98a5e5b58e593e8375be181c..05b68fc0d1f0e2a6cacdc7a8447b7cba3b52808c 100644 --- a/scripts/binauralRenderer_interface/generate_ivas_binauralizer_tables_from_sofa.m +++ b/scripts/binauralRenderer_interface/generate_ivas_binauralizer_tables_from_sofa.m @@ -53,15 +53,17 @@ normalizeSofaInputData = false; %% if true SOFA IR are nomalized ivas_path = ['..' filesep '..' filesep]; generateCustomBinaryFile = false; +generateBinaryFile_fx = false; +generate_BE = true; %% Set input files if generateCustomBinaryFile hrir_file_name_init = 'HRIR_128_Meth5_IRC_51_Q10_symL_Itrp1_48000.sofa'; - hrir_file_name = 'HRIR_128_Meth5_IRC_51_Q10_symL_Itrp1_48000_norm.sofa'; + hrir_file_name = 'HRIR_128_Meth5_IRC_51_Q10_symL_Itrp1_48000.sofa'; output_bin_name = 'ivas_binaural_51_brir-lc'; else hrir_file_name_init = 'HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'; - hrir_file_name = 'HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000_norm.sofa'; + hrir_file_name = 'HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa'; output_bin_name = 'ivas_binaural'; end brir_file_name = 'IIS_BRIR_officialMPEG_Combined.sofa'; @@ -213,6 +215,37 @@ if writeBinaryOutput == true error(cmdout) return end + + if generateBinaryFile_fx + td_binary_file = ['td_' erase(hrir_file_name,'.sofa') '_model_v003']; + command = ['.' filesep() 'Table_Format_Converter' filesep() 'tables_format_converter']; + binary_name = [binary_name '_fx']; + output_bin_name = [output_bin_name '_fx']; + command = [command ... + ' -output_file_path ' binary_path ... + ' -output_file_name ' output_bin_name ... + ' -input_mixerconv_hrir_file_path ' binary_path ... + ' -input_mixerconv_hrir_file_name ' binary_name ... + ' -input_mixerconv_brir_file_path ' binary_path ... + ' -input_mixerconv_brir_file_name ' binary_name ... + ' -input_reverb_file_path ' binary_path ... + ' -input_reverb_file_name ' binary_name ... + ' -input_td_file_path ' fullfile(binary_path, 'IVAS_default') ... + ' -input_td_file_name ' td_binary_file ... + ' -input_param_file_path ' binary_path ... + ' -input_param_file_name ' param_bin_file ... + ' -input_fastconv_file_path ' binary_path ... + ' -input_fastconv_file_name ' fastconv_bin_file ... + ]; + + [status, cmdout] = system(command); + if status ~= 0 + error(cmdout) + return + end + end + + end %% Foa all previously generated binary files, convert to binary files for IVAS decoder or renderer. One per sample rates and per renderers diff --git a/scripts/binauralRenderer_interface/ivas_crend_binaural_filter_design.c b/scripts/binauralRenderer_interface/ivas_crend_binaural_filter_design.c index 210eaffab3ef5fb2268a1198a25ef72140409336..13c2bcf028dc3e945086b205871f4665760e8735 100644 --- a/scripts/binauralRenderer_interface/ivas_crend_binaural_filter_design.c +++ b/scripts/binauralRenderer_interface/ivas_crend_binaural_filter_design.c @@ -171,6 +171,21 @@ static void printfAudioBufferOutFilterParams( } #endif +Word32 float2Word32( float val, Word16 Q ) +{ + Word32 retval; + float tmp = powf( 2.f, (float) Q ); + retval = (Word32) roundf( val * tmp ); + return retval; +} + +Word16 float2Word16( float val, Word16 Q ) +{ + Word16 retval; + float tmp = powf( 2.f, (float) Q ); + retval = (Word16) roundf( val * tmp ); + return retval; +} ivas_error ivas_hrtf_close( HRTFS_HANDLE hHRTF /* i/o: HRTF handle */ @@ -404,7 +419,6 @@ ivas_error ivas_crend_binaural_filter_design_compute_filters_params( indBeginMini = *index_start = (int32_t) round( ( pFirData->latency_s[0][0] - (double) pParam->latency_s ) * (double) pFirData->sampling_rate ); } - /************************************************************************/ /* Case HRIR (len <= 1024) -> fill FilterParam struct and quit function */ /************************************************************************/ @@ -1220,6 +1234,7 @@ ivas_error ivas_crend_binaural_filter_design_set_hrtf_fr( { pParam->pOut_to_bin_diffuse_re[i_ear] = (float *) malloc( totSizeFreqDiffuse * sizeof( float ) ); pParam->pOut_to_bin_diffuse_im[i_ear] = (float *) malloc( totSizeFreqDiffuse * sizeof( float ) ); + offset = 0; for ( i_block = 0; i_block < pParam->num_iterations_diffuse[0]; ++i_block ) { @@ -1269,6 +1284,7 @@ ivas_error ivas_crend_binaural_filter_design_set_hrtf_fr( pParam->pOut_to_bin_diffuse_re[i_ear][offset + i_tap] = pBlockSpectrum_r[i_tap]; pParam->pOut_to_bin_diffuse_im[i_ear][offset + i_tap] = pBlockSpectrum_i[i_tap]; } + offset = offset + pParam->pIndex_frequency_max_diffuse[i_ear][i_block]; } } @@ -1304,16 +1320,13 @@ ivas_error ivas_crend_binaural_filter_design_set_hrtf_fr( ivas_error ivas_set_hrtf_fr( HRTFS_DATA *crend_hrtf, ivas_hrtf_t *hrtf, - const int16_t output_frame - , - float mdft_scale_fact -) + const int16_t output_frame, + float mdft_scale_fact ) { int32_t i, j, m, n; float data_ir_flt[L_FRAME48k] = { 0.0f }; int32_t tmp_ir_len, in_len, k; - crend_hrtf->max_num_ir = (int16_t) hrtf->m; crend_hrtf->latency_s = (float) hrtf->latency_s[0][0]; @@ -1332,6 +1345,7 @@ ivas_error ivas_set_hrtf_fr( { return IVAS_ERR_FAILED_ALLOC; } + n = 0; tmp_ir_len = 0; diff --git a/scripts/binauralRenderer_interface/make_be_with_fx.m b/scripts/binauralRenderer_interface/make_be_with_fx.m new file mode 100644 index 0000000000000000000000000000000000000000..ba023654405266635d562f710d52a30f70cab241 --- /dev/null +++ b/scripts/binauralRenderer_interface/make_be_with_fx.m @@ -0,0 +1,8 @@ +function [y,factorQ] = make_be_with_fx(x,Q) +y = x; +factorQ = int16(0); +valMax = max(max(abs(real(x)),[],"all"), max(abs(imag(y)),[],"all")); +if ( valMax > 0 ) + factorQ = int16(floor( double(Q) - log( valMax ) / log( 2. ) )); + y = double(int32(x .* (2.^double(factorQ)))).* (2.^double(-factorQ)); +end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/compute_lr_energies_and_iac.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/compute_lr_energies_and_iac.m deleted file mode 100644 index 625b6a1161af9f9dc5bcbf7367f4a012d8130c7a..0000000000000000000000000000000000000000 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/compute_lr_energies_and_iac.m +++ /dev/null @@ -1,101 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, -% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -% contributors to this repository. All Rights Reserved. -% -% This software is protected by copyright law and by international treaties. -% The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, -% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -% contributors to this repository retain full ownership rights in their respective contributions in -% the software. This notice grants no license of any kind, including but not limited to patent -% license, nor is any license granted by implication, estoppel or otherwise. -% -% Contributors are required to enter into the IVAS codec Public Collaboration agreement before making -% contributions. -% -% This software is provided "AS IS", without any express or implied warranties. The software is in the -% development stage. It is intended exclusively for experts who have experience with such software and -% solely for the purpose of inspection. All implied warranties of non-infringement, merchantability -% and fitness for a particular purpose are hereby disclaimed and excluded. -% -% Any dispute, controversy or claim arising under or in relation to providing this software shall be -% submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in -% accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and -% the United Nations Convention on Contracts on the International Sales of Goods. -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function [left_avg_power, right_avg_power, ia_coherence] = compute_lr_energies_and_iac(HRTF_mdfts, in_freq_count, out_freq_count) - % Compute left/right and coherence of entire HRTF dataset - % - % HRTF_mdfts - HRTF dataset in frequency domain. - % in_freq_count - number of HRTF bins - % out_freq_count - number of bins in target for energies and coherence - % values - - hrtf_count = size(HRTF_mdfts,3); - - left_avg_power = zeros(1, out_freq_count); - right_avg_power = zeros(1, out_freq_count); - ia_coherence = zeros(1, out_freq_count); - - inp_freq_step = 0.5 / in_freq_count; - inp_freq_offset = 0.5 * inp_freq_step; - out_freq_step = 0.5 / (out_freq_count - 1); - - base_idx = 1; - relative_pos = 0; - - % loop over output frequency bins - for out_bin_idx=0:out_freq_count-1 - norm_freqs = out_freq_step * out_bin_idx; - tbl_index = ( norm_freqs - inp_freq_offset ) / inp_freq_step; - if (tbl_index <= 0.0) - base_idx = 0; - relative_pos = 0; - else - base_idx = int16(floor(tbl_index)); - relative_pos = tbl_index - double(base_idx); - % extrapolation (above last bin), choose nearest - if(base_idx > (in_freq_count-2)) - base_idx = in_freq_count-2; - relative_pos = 1; - end - end - - base_idx = base_idx +1; - IA_coherence = zeros(2,1); - avg_pwr_lr = zeros(2,2); - - for hrtf_idx=1:hrtf_count - lr_pair_0 = HRTF_mdfts(base_idx,:,hrtf_idx); - lr_pair_1 = HRTF_mdfts(base_idx + 1,:,hrtf_idx); - avg_pwr_lr(1,:) = avg_pwr_lr(1,:) + real(lr_pair_0).^2 + imag(lr_pair_0).^2; - avg_pwr_lr(2,:) = avg_pwr_lr(2,:) + real(lr_pair_1).^2 + imag(lr_pair_1).^2; - IA_coherence(1,1) = IA_coherence(1,1) + real(lr_pair_0(1)) * real(lr_pair_0(2)) + imag(lr_pair_0(1)) * imag(lr_pair_0(2)); - IA_coherence(2,1) = IA_coherence(2,1) + real(lr_pair_1(1)) * real(lr_pair_1(2)) + imag(lr_pair_1(1)) * imag(lr_pair_1(2)); - end - - % compute averages and IA coherence - avg_pwr_lr = avg_pwr_lr/hrtf_count; - IA_coherence = IA_coherence/hrtf_count; - IA_coherence(1,1) = IA_coherence(1,1) / sqrt((avg_pwr_lr(1,1) * avg_pwr_lr(1,2))); - IA_coherence(2,1) = IA_coherence(2,1) / sqrt((avg_pwr_lr(2,1) * avg_pwr_lr(2,2))); - - % Limiting to (0...1) range in case of small numerical errors or negative values - for i=1:2 - IA_coherence(i,1) = min(IA_coherence(i,1),1); - IA_coherence(i,1) = max(IA_coherence(i,1),0); - end - - % Computing weighted average of 2 nearest values (1 below + 1 above) for linear interpolation - weight_1st = 1 - relative_pos; - left_avg_power(out_bin_idx + 1) = weight_1st * avg_pwr_lr(1,1) + relative_pos * avg_pwr_lr(2,1); - right_avg_power(out_bin_idx + 1) = weight_1st * avg_pwr_lr(1,2) + relative_pos * avg_pwr_lr(2,2); - ia_coherence(out_bin_idx + 1) = weight_1st * IA_coherence(1,1) + relative_pos * IA_coherence(2,1); - end -end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_lr_energies_and_iac.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_lr_energies_and_iac.m deleted file mode 100644 index a67ba8267c9b9cd8309d546fd72ec52378c4b822..0000000000000000000000000000000000000000 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_lr_energies_and_iac.m +++ /dev/null @@ -1,111 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, -% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -% contributors to this repository. All Rights Reserved. -% -% This software is protected by copyright law and by international treaties. -% The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, -% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -% contributors to this repository retain full ownership rights in their respective contributions in -% the software. This notice grants no license of any kind, including but not limited to patent -% license, nor is any license granted by implication, estoppel or otherwise. -% -% Contributors are required to enter into the IVAS codec Public Collaboration agreement before making -% contributions. -% -% This software is provided "AS IS", without any express or implied warranties. The software is in the -% development stage. It is intended exclusively for experts who have experience with such software and -% solely for the purpose of inspection. All implied warranties of non-infringement, merchantability -% and fitness for a particular purpose are hereby disclaimed and excluded. -% -% Any dispute, controversy or claim arising under or in relation to providing this software shall be -% submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in -% accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and -% the United Nations Convention on Contracts on the International Sales of Goods. -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function data_struct = generate_lr_energies_and_iac(sofa_path, sofa_file_name) - % Generate left and right energies and coherence for late reverb from - % HRIRs. - % - % sofa_path - path to the directory that contains the sofa files to be - % converted. - % sofa_file - file name of the HRTFs to be converted - % - % Typical usage: - % generate_lr_energies_and_iac('../HRIRs_sofa', 'HRIR_128_Meth5_IRC_53_Q10_symL_Itrp1_48000.sofa') - % - -audio_format.names(1:4) = {'510'; '710'; '512'; '714'}; - -audio_format.az(1,1:4) = {[30 330 0 110 250]; ... - [30 330 0 110 250 135 225]; ... - [30 330 0 110 250 90 270]; ... - [30 330 0 110 250 135 225 45 315 135 225];}; -audio_format.el(1,1:4) = {[0 0 0 0 0]; ... - [0 0 0 0 0 0 0]; ... - [0 0 0 0 0 45 45]; ... - [0 0 0 0 0 0 0 45 45 45 45];}; - - data_struct = struct.empty(1,0); - sr = [48000, 32000, 16000]; - sr_short = [48, 32, 16]; - sr_dft_size = [240, 160, 80]; - - H = hrtf_library_loader(); - H.readSOFA(char(fullfile(sofa_path, sofa_file_name))); - -Az = squeeze(H.PosSpherical(1,:)) * 180 / pi; -El = squeeze(H.PosSpherical(2,:)) * 180 / pi; - - -indexEl0 = find(El == 0); -indexEl45 = find(El == 42); - -indFmt= 1; - - azis = cell2mat(audio_format.az(indFmt)); - eles = cell2mat(audio_format.el(indFmt)); - -indexPos = []; - -for ind2 = 1 : length(azis) - if (eles(ind2) == 0) - index = find(abs(Az(indexEl0) - azis(ind2)) < 0.0001); - indexPos = [indexPos indexEl0(index)]; - else - index = find(abs(Az(indexEl45) - azis(ind2)) < 0.0001); - indexPos = [indexPos indexEl45(index)]; - end -end - -SourcePosition = [Az(indexPos); El(indexPos); ones(1,length(azis)) * 2 ]'; - - - % 48kHz - IRs_all = permute(H.get_Discrete_HRTFs(), [1,3,2]); - % IRs = IRs_all(:,:,indexPos) * H.Gain; - IRs = IRs_all * H.Gain; - HRTF_mdfts = m_dft(IRs, sr_dft_size(1)); - [left_avg_power, right_avg_power, ia_coherence] = compute_lr_energies_and_iac(HRTF_mdfts, sr_dft_size(1), 257); - - % 32 kHz - % TODO - - % 16 kHz - % TODO - - % - data_struct(1).lr_energies_iac_48kHz = [left_avg_power; right_avg_power; ia_coherence]; - data_struct(1).lr_energies_iac_32kHz = []; - data_struct(1).lr_energies_iac_16kHz = []; - data_struct(1).sr = sr; - data_struct(1).sr_short = sr_short; - data_struct(1).sr_dft_size = sr_dft_size; - -end \ No newline at end of file diff --git a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/writeData3L.m b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/writeData3L.m index 56f6a3908199218390dd514e44d74c12c0271146..ff9a2950dac562e18936f83d0c66d9125e05c16d 100644 --- a/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/writeData3L.m +++ b/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/writeData3L.m @@ -29,7 +29,7 @@ % the United Nations Convention on Contracts on the International Sales of Goods. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -function writeData3L(fid_source, startstring, data) +function writeData3L(fid_source, startstring, floatformat, data) indices=size(data); indent = 4; @@ -50,7 +50,7 @@ for A = 1:indices(1) end counter=1; for C = 1:indices(3) - fprintf(fid_source,'%+ff',real(data(A,B,C))); + fprintf(fid_source,floatformat,real(data(A,B,C))); if C < indices(3) if mod(counter,10) == 0 fprintf(fid_source,','); diff --git a/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m b/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m index c9190516bd909c3aa0d804c54b2cada1ef523b2b..17d76ed351df6b21a17392bc5478903f934eccb1 100644 --- a/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m +++ b/scripts/binauralRenderer_interface/param_bin/generate_BRIR_in_SHD_CLDFB_PARAMETRIC.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., @@ -27,6 +28,8 @@ % 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. % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function [T60, lateEnes, earlyEnes] = generate_BRIR_in_SHD_CLDFB_PARAMETRIC(brir_inputfile, SHhrtf) % diff --git a/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m b/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m index a6dd95a297ecfcef38b42083fdb20b966ed2dd3a..75b31a749f394a2dd16708df32a0c08a440ff57a 100644 --- a/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m +++ b/scripts/binauralRenderer_interface/param_bin/generate_HRIR_in_SHD_CLDFB_PARAMETRIC.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., @@ -27,6 +28,7 @@ % 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. % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function SHhrtf = generate_HRIR_in_SHD_CLDFB_PARAMETRIC(hrir_inputfile) % @@ -148,7 +150,7 @@ function FD = CLDFB(sig) % Modulate prototype by half bin, and scale to match C implementation proto = proto.*exp(-1j*[0.5:1:600]'/120*pi) / 0.75; numCh = size(sig, 2); - sig = sig(1:end-mod(size(sig),60), :); + sig = sig(1:end-mod(length(sig),60), :); FD = zeros(60, size(sig,1)/60, numCh); sig = [zeros(540, numCh); sig]; indices = [1:600]'; diff --git a/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m index ecea9035e9178d7984cc776da49edcf28ffd3d1d..bc14e5e6877673ee7ff3061dc5d12451ebed526e 100644 --- a/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m +++ b/scripts/binauralRenderer_interface/param_bin/generate_tables_for_parametric_binauralizer.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., @@ -27,6 +28,8 @@ % 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. % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % % Generate tables from given HRIRs and BRIRs for IVAS binaural renderers PARAMETRIC and FASTCONV @@ -51,6 +54,15 @@ end if ~exist("writeBinaryOutput",'var') writeBinaryOutput = true; end +if ~exist("generateCustomBinaryFile",'var') + generateCustomBinaryFile = false; +end +if ~exist("generateBinaryFile_fx",'var') + generateBinaryFile_fx = false; +end +if ~exist("generate_BE",'var') + generate_BE = true; +end if ~exist("rom_file",'var') rom_file = fullfile('.', 'ivas_rom_binauralRenderer.c'); end @@ -84,26 +96,60 @@ end disp('Processing HRIR for parametric renderer...'); SHhrtf = generate_HRIR_in_SHD_CLDFB_PARAMETRIC(hrir_file); +%% compute scaling factor and ste floating point precision to word32 +if generate_BE == false + [SHhrtf, factorQ_SHhrtf] = make_be_with_fx(SHhrtf,15); +end + if writeRomFileOutput - writeData3L(fid, 'const float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]', real(SHhrtf)); - writeData3L(fid, 'const float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]', imag(SHhrtf)); + if generate_BE + writeData3L(fid, 'const float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]','%+ff', real(SHhrtf)); + writeData3L(fid, 'const float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]','%+ff', imag(SHhrtf)); + else + writeData3L(fid, 'const uint32_t hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]', '0x%tx', real(SHhrtf)); + writeData3L(fid, 'const uint32_t hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]', '0x%tx',imag(SHhrtf)); + end end %% Generate C-code tables for RENDERER_BINAURAL_PARAMETRIC_ROOM (SHD) disp('Processing BRIR for parametric renderer...'); [T60, lateEnes, earlyEnes] = generate_BRIR_in_SHD_CLDFB_PARAMETRIC(brir_file, SHhrtf); +if generateCustomBinaryFile == true + T60 = T60 * 2; + lateEnes = lateEnes * 2; + earlyEnes = earlyEnes * 2; +end + +%% compute scaling factor and ste floating point precision to word32 +if generate_BE == false + [T60, factorQ_T60] = make_be_with_fx(T60,15); + [lateEnes, factorQ_lateEnes] = make_be_with_fx(lateEnes,15); + [earlyEnes, factorQ_earlyEnes] = make_be_with_fx(earlyEnes,15); +end if writeRomFileOutput % Write BRIR parameters to file - fprintf(fid, 'const float parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX] = {\n'); + if generate_BE + fprintf(fid, 'const float parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX] = {\n'); + else + fprintf(fid, 'const uint32_t parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX] = {\n'); + end for k = 1:60 if mod(k-1, 10)==0 fprintf(fid, ' '); end if k < 60 - fprintf(fid, '%ff,', T60(k)); + if generate_BE + fprintf(fid, '%+ff,', T60(k)); + else + fprintf(fid, '0x%tx,', T60(k)); + end else - fprintf(fid, '%ff\n};', T60(k)); + if generate_BE + fprintf(fid, '%+ff\n};', T60(k)); + else + fprintf(fid, '0x%tx\n};', T60(k)); + end end if k>1 && mod(k, 10)==0 fprintf(fid, '\n'); @@ -112,15 +158,27 @@ if writeRomFileOutput end end - fprintf(fid, '\n\nconst float parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = {\n'); + if generate_BE + fprintf(fid, '\n\nconst float parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = {\n'); + else + fprintf(fid, '\n\nconst uint32_t parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX] = {\n'); + end for k = 1:60 if mod(k-1, 10)==0 fprintf(fid,' '); end if k < 60 - fprintf(fid, '%ff,', lateEnes(k)); + if generate_BE + fprintf(fid, '%+ff,', lateEnes(k)); + else + fprintf(fid, '0x%tx,', lateEnes(k)); + end else - fprintf(fid, '%ff\n};', lateEnes(k)); + if generate_BE + fprintf(fid, '%+ff\n};', lateEnes(k)); + else + fprintf(fid, '0x%tx\n};', lateEnes(k)); + end end if k>1 && mod(k, 10)==0 fprintf(fid, '\n'); @@ -129,15 +187,27 @@ if writeRomFileOutput end end - fprintf(fid, '\n\nconst float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX] = {\n'); + if generate_BE + fprintf(fid, '\n\nconst float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX] = {\n'); + else + fprintf(fid, '\n\nconst uint32_t parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX] = {\n'); + end for k = 1:60 if mod(k-1, 10)==0 fprintf(fid, ' '); end if k < 60 - fprintf(fid, '%ff,', earlyEnes(k)); + if generate_BE + fprintf(fid, '%+ff,', earlyEnes(k)); + else + fprintf(fid, '0x%tx,', earlyEnes(k)); + end else - fprintf(fid, '%ff\n};', earlyEnes(k)); + if generate_BE + fprintf(fid, '%+ff\n};', earlyEnes(k)); + else + fprintf(fid, '0x%tx\n};', earlyEnes(k)); + end end if k>1 && mod(k, 10)==0 fprintf(fid, '\n'); @@ -154,5 +224,8 @@ end %% if writeBinaryOutput write_parametric_binauralizer_binary_data(bin_file, SHhrtf, T60, lateEnes, earlyEnes); + if generateBinaryFile_fx + write_parametric_binauralizer_binary_data_fx(bin_file, SHhrtf, factorQ_SHhrtf, T60, factorQ_T60, lateEnes, factorQ_lateEnes,earlyEnes, factorQ_earlyEnes); + end %save('parambin_binary_rom.mat', 'SHhrtf', 'T60', 'lateEnes', 'earlyEnes'); % debug saving end diff --git a/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m index 27045b7a29e4c8d269a6b3b8e09fc913529da7a3..21c013120aa56957b1311a330feaba46aeca7ca6 100644 --- a/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m +++ b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data.m @@ -1,3 +1,4 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., @@ -27,6 +28,8 @@ % 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. % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function write_parametric_binauralizer_binary_data(filename, SHhrtf, T60, late_enes, early_enes) % diff --git a/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data_fx.m b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data_fx.m new file mode 100644 index 0000000000000000000000000000000000000000..cb3434500bdcac6a9be0ca6fb288ab83a094c076 --- /dev/null +++ b/scripts/binauralRenderer_interface/param_bin/write_parametric_binauralizer_binary_data_fx.m @@ -0,0 +1,113 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +% contributors to this repository. All Rights Reserved. +% +% This software is protected by copyright law and by international treaties. +% The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +% Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +% Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +% Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +% contributors to this repository retain full ownership rights in their respective contributions in +% the software. This notice grants no license of any kind, including but not limited to patent +% license, nor is any license granted by implication, estoppel or otherwise. +% +% Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +% contributions. +% +% This software is provided "AS IS", without any express or implied warranties. The software is in the +% development stage. It is intended exclusively for experts who have experience with such software and +% solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +% and fitness for a particular purpose are hereby disclaimed and excluded. +% +% Any dispute, controversy or claim arising under or in relation to providing this software shall be +% submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +% accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +% the United Nations Convention on Contracts on the International Sales of Goods. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +function write_parametric_binauralizer_binary_data_fx(filename, SHhrtf, factorQ_SHhrtf, T60, factorQ_T60, late_enes, factorQ_lateEnes,early_enes, factorQ_earlyEnes) +% +% Writes HRIR & BRIR based data for parametric binauralizer into a binary file. +% +% write_parametric_binauralizer_binary_data(filename, SHhrtf, T60, late_enes, early_enes) +% +% filename : string +% name of the file to be written +% SHhrtf : array of shape (2, 16, 60) i.e., (BINAURAL_CHANNELS, HRTF_SH_CHANNELS, HRTF_NUM_BINS), complex-valued +% HRTF coefficients +% T60 : array of shape (60, 1), i.e., (CLDFB_NO_CHANNELS_MAX, 1), double +% late_enes : array of shape (1, 60), i.e., (1, CLDFB_NO_CHANNELS_MAX), double +% early_enes : array of shape (1, 60), i.e., (1, CLDFB_NO_CHANNELS_MAX), double +% +% +% Output file format: +% HRTFs +% HRTF_SH_CHANNELS => uint16_t +% HRTF_NUM_BINS => uint16_t +% hrtfShCoeffsRe => int16_t[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; +% hrtfShCoeffsIm => int16_t[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; +% +% BRIR-based reverb +% CLDFB_NO_CHANNELS_MAX => uint16_t +% parametricReverberationTimes => int16_t[CLDFB_NO_CHANNELS_MAX]; +% parametricReverberationEneCorrections => int16_t[CLDFB_NO_CHANNELS_MAX]; +% parametricEarlyPartEneCorrection => int16_t[CLDFB_NO_CHANNELS_MAX]; +% + +filename = [erase(filename,'.bin') '_fx.bin' ]; + +[f_id, err_msg] = fopen(filename, 'wb'); + +if f_id == -1 + error('Could not open file %s for writing. Error message:\n%s', filename, err_msg); +end + +% HRTFs +n_chnls_bin = 2; +hrtf_sh_channels = size(SHhrtf, 2); +hrtf_num_bins = size(SHhrtf, 3); + +fwrite(f_id, hrtf_sh_channels, 'uint16'); +fwrite(f_id, hrtf_num_bins, 'uint16'); + +SHhrtf = SHhrtf .* (2.^double(factorQ_SHhrtf)); +fwrite(f_id, factorQ_SHhrtf, 'uint16'); + +% hrtfShCoeffsRe +for bin_chnl_idx = 1:n_chnls_bin + for hrtf_chnl_idx = 1:hrtf_sh_channels + fwrite(f_id, real(SHhrtf(bin_chnl_idx, hrtf_chnl_idx, :)), 'int16'); % HRTF_NUM_BINS elements + end +end + +% hrtfShCoeffsIm +for bin_chnl_idx = 1:n_chnls_bin + for hrtf_chnl_idx = 1:hrtf_sh_channels + fwrite(f_id, imag(SHhrtf(bin_chnl_idx, hrtf_chnl_idx, :)), 'int16'); % HRTF_NUM_BINS elements + end +end + +% BRIR-based reverb +cldfb_no_channels_max = size(T60, 1); + +fwrite(f_id, cldfb_no_channels_max, 'uint16'); + +T60 = T60 .* (2.^double(factorQ_T60)); +fwrite(f_id, factorQ_T60, 'uint16'); +fwrite(f_id, int16(T60), 'int16'); % parametricReverberationTimes + +late_enes = late_enes .* (2.^double(factorQ_lateEnes)); +fwrite(f_id, factorQ_lateEnes, 'uint16'); +fwrite(f_id, int16(late_enes), 'int16'); % parametricReverberationEneCorrections + +early_enes = early_enes .* (2.^double(factorQ_earlyEnes)); +fwrite(f_id, factorQ_earlyEnes, 'uint16'); +fwrite(f_id, int16(early_enes), 'int16'); % parametricEarlyPartEneCorrection + +fclose(f_id); diff --git a/scripts/check-format.sh b/scripts/check-format.sh index 079a1ed334ce12f2b702cfb2fa210865700e3e6f..db6c681e9dfd515db91e8ed78da252ef06536769 100755 --- a/scripts/check-format.sh +++ b/scripts/check-format.sh @@ -69,6 +69,16 @@ cl-format-apply() { ${CLANG_FORMAT} -i $1 } +ensure-one-newline() +{ + # first command adds a newline at the end of the file if there might be none + # -> clang-format-13 does not add them and warnings e.g. on MacOS are triggered by them + sed -i -e '$a\' $1 + # second command removes multiple newlines at the end of a file so that there is only one left + # -> clang-format-13 does not do that, but complains about it + sed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' $1 +} + cl-format-check() { local I=$1 local COLOR=$2 @@ -160,7 +170,7 @@ fi if [ -z "$FILES" ]; then if [ $ALL ]; then - FILES=$(ls lib_com/*.[c,h] lib_dec/*.[c,h] lib_enc/*.[c,h] lib_rend/*.[c,h] lib_util/*.[c,h] apps/*.[c,h]) + FILES=$(ls lib_com/*.[c,h] lib_dec/*.[c,h] lib_enc/*.[c,h] lib_isar/*.[c,h] lib_rend/*.[c,h] lib_util/*.[c,h] apps/*.[c,h]) elif [ -d ".svn" ]; then if [ ! -x "$(command -v svn)" ]; then echo "Subversion doesn't seem to be installed. Please ensure svn is in your PATH" @@ -197,6 +207,7 @@ if [[ $NUMPROCS -lt 2 ]]; then RET=$? ((NUMFAILS+=RET)) if [ $FORMAT ]; then + ensure-one-newline $i cl-format-apply $i fi done @@ -218,6 +229,7 @@ else fi ((NUMFAILS+=RET)) if [ $FORMAT ]; then + ensure-one-newline $i cl-format-apply $i fi ) & while [[ $(jobs -r -p | wc -l) -ge $NUMPROCS ]];do diff --git a/scripts/cleanup_26252.py b/scripts/cleanup_26252.py new file mode 100644 index 0000000000000000000000000000000000000000..2df321a1d419002c27c265bad50618b8558d6a20 --- /dev/null +++ b/scripts/cleanup_26252.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + +from pathlib import Path +import os +import glob + +files = ['Readme_IVAS_JBM_dec.txt','Readme_IVAS_dec.txt','Readme_IVAS_enc.txt','Readme_IVAS_rend.txt', 'Readme_IVAS_ISAR_dec.txt', 'Readme_IVAS_ISAR_post_rend.txt']; + +used_files = [] +kept = 0 +removed = 0 + +# Input files explicitly listed in scripts +for file in files: + with open(file,"r") as fp: + for line in fp: + for item in line.split(): + if "$TESTV_PATH" in item or "$REF_PATH" in item: + used_files.append(Path(item).name) + +# All .dat files in testv (binary render config files listed via txt config file) +for file in glob.glob("testvec/testv/*.dat"): + used_files.append(Path(file).name) + +# All .met, .csv and .wav files in .txt configuration files +for file in glob.glob("testvec/testv/*.txt"): + with open(file,"r") as fp: + for line in fp: + if any(x in line for x in [".met",".csv",".wav"]): + used_files.append(Path(line).name.strip()) + +# Remove duplicates +used_files = list(dict.fromkeys(used_files)) + +for dirpath, subdirs, files in os.walk("testvec"): + for file in files: + if file in used_files: + kept = kept + 1 + else: + removed = removed + 1 + os.remove(os.path.join(dirpath, file)) +print(f"Identified {len(used_files)} files from scripts") +print(f"Removed {removed} files") +print(f"Kept {kept} files") + + diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 42b4d2b6a4afa7a244e42ff385987ca0302f00d3..1ba398353649aaac74b63db50106a242fb7c3385 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -622,7 +622,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "FOA", "table_name": "FOA@{table_bitrate} kbps {bandwidth}", @@ -702,7 +703,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "FOA", "table_name": "FOA@{table_bitrate} kbps DTX {bandwidth}", @@ -760,7 +762,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "FOA", "table_name": "FOA@{table_bitrate} kbps RS {bandwidth}", @@ -805,7 +808,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA2", "table_name": "HOA2@{table_bitrate} kbps {bandwidth}", @@ -885,7 +889,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA2", "table_name": "HOA2@{table_bitrate} kbps DTX {bandwidth}", @@ -943,7 +948,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA2", "table_name": "HOA2@{table_bitrate} kbps RS {bandwidth}", @@ -988,7 +994,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA3", "table_name": "HOA3@{table_bitrate} kbps {bandwidth}", @@ -1068,7 +1075,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA3", "table_name": "HOA3@{table_bitrate} kbps DTX {bandwidth}", @@ -1126,7 +1134,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA3", "table_name": "HOA3@{table_bitrate} kbps RS {bandwidth}", @@ -1171,7 +1180,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "FOA", "table_name": "Planar FOA@{table_bitrate} kbps {bandwidth}", @@ -1251,7 +1261,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "FOA", "table_name": "Planar FOA@{table_bitrate} kbps DTX {bandwidth}", @@ -1309,7 +1320,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "FOA", "table_name": "Planar FOA@{table_bitrate} kbps RS {bandwidth}", @@ -1354,7 +1366,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA2", "table_name": "Planar HOA2@{table_bitrate} kbps {bandwidth}", @@ -1434,7 +1447,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA2", "table_name": "Planar HOA2@{table_bitrate} kbps DTX {bandwidth}", @@ -1492,7 +1506,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA2", "table_name": "Planar HOA2@{table_bitrate} kbps RS {bandwidth}", @@ -1537,7 +1552,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA3", "table_name": "Planar HOA3@{table_bitrate} kbps {bandwidth}", @@ -1617,7 +1633,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA3", "table_name": "Planar HOA3@{table_bitrate} kbps DTX {bandwidth}", @@ -1675,7 +1692,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "HOA3", "table_name": "Planar HOA3@{table_bitrate} kbps RS {bandwidth}", @@ -2135,7 +2153,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "5_1", "table_name": "MC 5_1@{table_bitrate} kbps {bandwidth}", @@ -2214,7 +2233,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "7_1", "table_name": "MC 7_1@{table_bitrate} kbps {bandwidth}", @@ -2293,7 +2313,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "5_1_2", "table_name": "MC 5_1_2@{table_bitrate} kbps {bandwidth}", @@ -2372,7 +2393,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "5_1_4", "table_name": "MC 5_1_4@{table_bitrate} kbps {bandwidth}", @@ -2451,7 +2473,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "7_1_4", "table_name": "MC 7_1_4@{table_bitrate} kbps {bandwidth}", @@ -2530,7 +2553,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "5_1", "table_name": "MC 5_1@{table_bitrate} kbps RS {bandwidth}", @@ -2573,7 +2597,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "7_1", "table_name": "MC 7_1@{table_bitrate} kbps RS {bandwidth}", @@ -2616,7 +2641,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "5_1_2", "table_name": "MC 5_1_2@{table_bitrate} kbps RS {bandwidth}", @@ -2659,7 +2685,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "5_1_4", "table_name": "MC 5_1_4@{table_bitrate} kbps RS {bandwidth}", @@ -2702,7 +2729,8 @@ "HOA2": [], "FOA": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "7_1_4", "table_name": "MC 7_1_4@{table_bitrate} kbps RS {bandwidth}", @@ -4124,7 +4152,8 @@ "5_1_2": [], "5_1": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "STEREO", "table_name": "Stereo@{table_bitrate} kbps {bandwidth}", @@ -4191,7 +4220,8 @@ "5_1_2": [], "5_1": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "STEREO", "table_name": "Stereo@{table_bitrate} kbps DTX {bandwidth}", @@ -4257,7 +4287,8 @@ "5_1_2": [], "5_1": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "STEREO", "table_name": "stereo@{table_bitrate} kbps RS {bandwidth}", @@ -4299,7 +4330,8 @@ "5_1_2": [], "5_1": [], "mono": [], - "stereo": [] + "stereo": [], + "EXT": [] }, "in_config": "STEREO", "table_name": "stereo@{table_bitrate} kbps RS DTX {bandwidth}", diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index 2e9886b9ffcfd1343b478c46bce31b7a5a3beffd..3a071276cbaed462f5697410817246db13dc01d6 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -292,6 +292,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 //../IVAS_cod -dtx -stereo ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stvST48n.wav bit //../IVAS_dec MONO 48 bit testv/stvST48n.wav_stereo_sw_48-48_DTX_MONO.tst +// stereo bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, DTX on, EXT out +//../IVAS_cod -dtx -stereo ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stvST48c.wav bit +//../IVAS_dec EXT 48 bit testv/stvST48c.wav_stereo_sw_48-48_DTX_EXT.tst // 1 ISM with metadata at 13.2 kbps, 48 kHz in, 48 kHz out, EXT out @@ -533,7 +536,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -dtx -ism 4 testv/stvISM1.csv NULL NULL testv/stvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv4ISM48n.wav bit ../IVAS_dec HOA3 48 bit testv/stv4ISM48n.wav_brate_sw_48-48_DTX_hoa3.tst -// 4 ISM with and without metadata bitrate switching from 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL_ROOM_IR out (Model from file) +// 4 ISM w and wo md br switching 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL_ROOM_IR out (Model from file) ../IVAS_cod -dtx -ism 4 testv/stvISM1.csv NULL NULL testv/stvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv4ISM48n.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_IR 48 bit testv/stv4ISM48n.wav_brate_sw_48-48_DTX_hoa3.tst @@ -851,11 +854,11 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_dec 7_1_4 48 bit testv/stv3OA48c.wav_sw_48-48_7_1_4.tst // SBA FOA bitrate switching from 13.2 kbps to 192 kbps, 32kHz in, 32kHz out, DTX on, BINAURAL out -../IVAS_cod -dtx -sba 1 ../scripts/switchPaths/sw_13k2_192k_50fr.bin 32 testv/stvFOA32c.wav bit +../IVAS_cod -dtx -sba 1 ../scripts/switchPaths/sw_13k2_192k_50fr.bin 32 testv/stvFOA32c_cut_.004.wav bit ../IVAS_dec BINAURAL 32 bit testv/stvFOA32c.wav_sw_32-32_DTX_BINAURAL.tst // SBA 3OA bitrate switching from 13.2 kbps to 128 kbps, 32kHz in, 32kHz out, DTX on, HOA3 out -../IVAS_cod -dtx -sba 3 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 32 testv/stv3OA32c.wav bit +../IVAS_cod -dtx -sba 3 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 32 testv/stv3OA32c_cut_.004.wav bit ../IVAS_dec HOA3 32 bit testv/stv3OA32c.wav_sw_32-32_DTX_HOA3.tst // SBA FOA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, FOA out @@ -880,28 +883,41 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // SBA at 128 kbps, 32kHZ in, 32kHz out, BINAURAL_ROOM_REVERB out HR ../IVAS_cod -sba 3 128000 32 testv/stv3OA32c.wav bit -../IVAS_dec -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 32 bit testv/stv3OA32c.pcm_SBA_12800032-32_BinauralRoomReverb_Headrot.tst +../IVAS_dec -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 32 bit testv/stv3OA32c.pcm_SBA_128000_32-32_BinauralRoomReverb_Headrot.tst // SBA at 128 kbps, 32kHZ in, 32kHz out, BINAURAL_ROOM_REVERB out, Config renderer, HR ../IVAS_cod -sba 3 128000 32 testv/stv3OA32c.wav bit -../IVAS_dec -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stv3OA32c.pcm_SBA_12800032-32_BinauralRoomReverb_Config_renderer_Headrot.tst +../IVAS_dec -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stv3OA32c.pcm_SBA_128000_32-32_BinauralRoomReverb_Config_renderer_Headrot.tst // SBA at 128 kbps, 32kHZ in, 16kHz out, BINAURAL_ROOM_REVERB out (Model from file), HR ../IVAS_cod -sba 2 128000 32 testv/stv2OA32c.wav bit -../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 16 bit testv/stv2OA32c.pcm_SBA_12800032-16_BinauralRoomReverb_Headrot_BinauralFile.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 16 bit testv/stv2OA32c.pcm_SBA_128000_32-16_BinauralRoomReverb_Headrot_BinauralFile.tst // Planar SBA at 128 kbps, 48kHZ in, 32kHz out, BINAURAL_ROOM_REVERB out (Model from file), Config renderer, HR ../IVAS_cod -sba -1 128000 48 testv/stvFOA48c.wav bit -../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stvFOA48c.pcm_planarSBA_12800032-32_BinauralRoomReverb_Config_renderer_Headrot_BinauralFile.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/stvFOA48c.pcm_planarSBA_128000_48-32_BinauralRoomReverb_Config_renderer_Headrot_BinauralFile.tst // SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB rendconf sel acoustic env ../IVAS_cod -sba 3 128000 48 testv/stv3OA48c.wav bit -../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1 BINAURAL_ROOM_REVERB 48 bit testv/stv3OA48c.pcm_SBA_12800048-48_BinauralRoomReverb_Config_renderer_combined_AEID_1.tst +../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1 BINAURAL_ROOM_REVERB 48 bit testv/stv3OA48c.pcm_SBA_128000_48-48_BinauralRoomReverb_Config_renderer_combined_AEID_1.tst // SBA at 256 kbps, 48kHz in, 48kHz out, PCA, BINAURAL out ../IVAS_cod -pca -sba 1 256000 48 testv/stvFOA48c.wav bit ../IVAS_dec BINAURAL 48 bit testv/stvFOA48c.wav_SBA_PCA_256000_48-48_BINAURAL.tst +// SBA FOA bitrate switching from 13.2 kbps to 192 kbps, 32kHz in, 32kHz out, DTX on, EXT out +../IVAS_cod -dtx -sba 1 ../scripts/switchPaths/sw_13k2_192k_50fr.bin 32 testv/stvFOA32c.wav bit +../IVAS_dec EXT 32 bit testv/stvFOA32c.wav_sw_32-32_DTX_EXT.tst + +// SBA 2OA bitrate switching from 13.2 kbps to 128 kbps, 32kHz in, 32kHz out, DTX on, EXT out +../IVAS_cod -dtx -sba 2 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 32 testv/stv2OA32c.wav bit +../IVAS_dec EXT 32 bit testv/stv2OA32c.wav_sw_32-32_DTX_EXT.tst + +// SBA 3OA bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, DTX on, random FER at 5%, EXT out +../IVAS_cod -dtx -sba 3 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv3OA48c.wav bit +eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error +../IVAS_dec EXT 48 bit_error testv/stv3OA48c.wav_sw_48-48_DTX_EXT_FER5.tst + // MASA 1dir 1TC at 13.2 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_SWB.txt -masa 1 testv/stv1MASA1TC48c.met 13200 48 testv/stv1MASA1TC48c.wav bit @@ -1253,7 +1269,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // Multi-channel 7_1_4 at 160 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_IR out, HR ../IVAS_cod -max_band FB -mc 7_1_4 160000 48 testv/stv714MC48c.wav bit -../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/stv714MC48c.wav_MC714_160000_48-16_MC_binaural-HR.tst +../IVAS_dec -t testv/headrot.csv BINAURAL 16 bit testv/stv714MC48c.wav_MC714_160000_48-16_MC_binaural-HR.tst // Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, 7_1_4 out ../IVAS_cod -mc 7_1_4 160000 48 testv/stv714MC48c.wav bit @@ -1320,7 +1336,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v2.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_ER_v2.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections, low complexity, listener origin +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Conf early refl, low complexity, listener origin ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v3.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_ER_v3.tst @@ -1336,6 +1352,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit ../IVAS_dec BINAURAL_ROOM_REVERB 16 bit testv/stv51MC48c.wav_sw_48-16_Binaural_room.tst +// Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 32kHz in, 48kHz out, BINAURAL_ROOM_IR out +../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 32 testv/stv51MC32c.wav bit +../IVAS_dec BINAURAL_ROOM_IR 48 bit testv/stv51MC32c.wav_sw_32-48_Binaural_room.tst + // Multi-channel 5_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, BINAURAL out, FER at 10%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -mc 5_1 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv51MC48c.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g192 bit_error @@ -1378,6 +1398,25 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 7_1_4 512000 48 testv/stv714MC48c.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_IR 48 bit testv/stv714MC48c.wav_MC714_512000_48-48_MC_binaural_room.tst +// Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, EXT out +../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv51MC48c.wav bit +../IVAS_dec HOA3 48 bit testv/stv51MC48c.wav_sw_48-48_EXT.tst + +// Multi-channel 5_1_2 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, EXT out +../IVAS_cod -mc 5_1_2 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv512MC48c.wav bit +../IVAS_dec EXT 48 bit testv/stv512MC48c.wav_sw_48-48_EXT.tst + +// Multi-channel 5_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 32kHz out, EXT out +../IVAS_cod -mc 5_1_4 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv514MC48c.wav bit +../IVAS_dec EXT 32 bit testv/stv514MC48c.wav_sw_48-32_EXT.tst + +// Multi-channel 7_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 16kHz out, EXT out +../IVAS_cod -mc 7_1 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv71MC48c.wav bit +../IVAS_dec EXT 16 bit testv/stv71MCMC48c.wav_sw_48-16_EXT.tst + +// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, EXT out +../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv714MC48c.wav bit +../IVAS_dec EXT 48 bit testv/stv714MC48c.wav_sw_48-48_EXT.tst // Stereo downmix to bit-exact EVS at 13200 kbps, 32kHz in, 32kHz out @@ -1501,7 +1540,6 @@ networkSimulator_g192 ../scripts/dly_error_profiles/dly_error_profile_5.dat bit ../IVAS_dec -non_diegetic_pan 80 STEREO 48 bit testv/stv1ISM48s.pcm_ISM_32000_48-48_STEREO_NON-DIEGETIC-PAN_80.tst - // OMASA 2Dir2TC 1ISM at 13.2 kbps, 48kHz in, 48kHz out, BINAURAL out ../IVAS_cod -ism_masa 1 2 NULL testv/stv2MASA2TC48c.met 13200 48 testv/stvOMASA_1ISM_2MASA2TC48c.wav bit ../IVAS_dec BINAURAL 48 bit testv/stvOMASA_1ISM_2MASA2TC48c.wav_BINAURAL_13200_48-48.tst @@ -1726,10 +1764,10 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_sba 4 3 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 32 testv/stvOSBA_4ISM_3OA32c.wav bit ../IVAS_dec EXT 48 bit testv/stvOSBA_4ISM_3OA32c.wav_EXT_sw_13k2_512k_32-48.tst -// OSBA FOA 4ISM at bitrate switching 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching +// OSBA FOA 4ISM at br sw 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_FB.txt -ism_sba 4 1 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stvOSBA_4ISM_FOA48c.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error -../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit_error testv/stvOSBA_4ISM_FOA48c.wav_BINAURAL_sw_48-48_FER5.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit_error testv/stvOSBA_4ISM_FOA48c.wav_BINAURAL_sw_48-16_FER5.tst // OSBA 3ISM 2OA at bitrate switching 13.2 to 512 kbps, 48kHz in, 32kHz out, STEREO out, FER at 10% ../IVAS_cod -ism_sba 3 2 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stvOSBA_3ISM_2OA48c.wav bit @@ -1755,3 +1793,16 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g // OSBA planar 2OA 4ISM at 512 kbps, 48 kHz in, 48 kHz out, BINAURAL ROOM REVERB (Model from file) out ../IVAS_cod -ism_sba 4 -2 testv/stvISM1.csv testv/stvISM2.csv testv/stvISM3.csv testv/stvISM4.csv 512000 48 testv/stvOSBA_4ISM_2OA48c.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_REVERB 48 bit testv/stvOSBA_4ISM_p3OA48c.wav_BINAURAL_ROOM_REVERB_512000_48-48.tst + +// SBA FOA bitrate switching from 13.2 kbps to 192 kbps, 32kHz in, 32kHz out, DTX on, EXT out +../IVAS_cod -dtx -sba 1 ../scripts/switchPaths/sw_13k2_192k_50fr.bin 32 testv/stvFOA32c_cut_.004.wav bit +../IVAS_dec EXT 32 bit testv/stvFOA32c.wav_sw_32-32_DTX_EXT.tst + +// SBA 3OA bitrate switching from 13.2 kbps to 128 kbps, 32kHz in, 32kHz out, DTX on, EXT out +../IVAS_cod -dtx -sba 3 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 32 testv/stv3OA32c_cut_.004.wav bit +../IVAS_dec EXT 32 bit testv/stv3OA32c.wav_sw_32-32_DTX_EXT.tst + +// SBA 2OA bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, EXT out, random FER at 5%, DTX on +../IVAS_cod -dtx -sba 3 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv3OA48c_cut_.004.wav bit +eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error +../IVAS_dec EXT 48 bit_error testv/stv3OA48c.wav_sw_48-48_EXT_FER5.tst diff --git a/scripts/config/self_test_ltv.prm b/scripts/config/self_test_ltv.prm index 690d3ed897cfe6bf0831b51aefd2bd5a14944323..2a66699563e2f906fbe186b5b19d8bd95d9d1b03 100644 --- a/scripts/config/self_test_ltv.prm +++ b/scripts/config/self_test_ltv.prm @@ -291,6 +291,9 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 //../IVAS_cod -dtx -stereo ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/ltv48_STEREO.wav bit //../IVAS_dec MONO 48 bit testv/ltv48_STEREO.wav_stereo_sw_48-48_DTX_MONO.tst +// stereo bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, DTX on, EXT out +//../IVAS_cod -dtx -stereo ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/ltv48_STEREO.wav bit +//../IVAS_dec EXT 48 bit testv/ltv48_STEREO.wav_stereo_sw_48-48_DTX_EXT.tst // 1 ISM with metadata at 13.2 kbps, 48 kHz in, 48 kHz out, EXT out @@ -532,7 +535,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -dtx -ism 4 testv/ltvISM1.csv NULL NULL testv/ltvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_4ISM.wav bit ../IVAS_dec HOA3 48 bit testv/ltv48_4ISM.wav_brate_sw_48-48_DTX_hoa3.tst -// 4 ISM with and without metadata bitrate switching from 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL_ROOM_IR out (Model from file) +// 4 ISM w and wo md br switching 24.4 kbps to 256 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL_ROOM_IR out (Model from file) ../IVAS_cod -dtx -ism 4 testv/ltvISM1.csv NULL NULL testv/ltvISM4.csv ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_4ISM.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_IR 48 bit testv/ltv48_4ISM.wav_brate_sw_48-48_DTX_hoa3.tst @@ -879,28 +882,41 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // SBA at 128 kbps, 32kHZ in, 32kHz out, BINAURAL_ROOM_REVERB out HR ../IVAS_cod -sba 3 128000 32 testv/ltv32_HOA3.wav bit -../IVAS_dec -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 32 bit testv/ltv32_HOA3.pcm_SBA_12800032-32_BinauralRoomReverb_Headrot.tst +../IVAS_dec -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 32 bit testv/ltv32_HOA3.pcm_SBA_128000_32-32_BinauralRoomReverb_Headrot.tst // SBA at 128 kbps, 32kHZ in, 32kHz out, BINAURAL_ROOM_REVERB out, Config renderer, HR ../IVAS_cod -sba 3 128000 32 testv/ltv32_HOA3.wav bit -../IVAS_dec -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/ltv32_HOA3.pcm_SBA_12800032-32_BinauralRoomReverb_Config_renderer_Headrot.tst +../IVAS_dec -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/ltv32_HOA3.pcm_SBA_128000_32-32_BinauralRoomReverb_Config_renderer_Headrot.tst // SBA at 128 kbps, 32kHZ in, 16kHz out, BINAURAL_ROOM_REVERB out (Model from file), HR ../IVAS_cod -sba 2 128000 32 testv/ltv32_HOA2.wav bit -../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 16 bit testv/ltv32_HOA2.pcm_SBA_12800032-16_BinauralRoomReverb_Headrot_BinauralFile.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin -t testv/headrot_case00_3000_q.csv BINAURAL_ROOM_REVERB 16 bit testv/ltv32_HOA2.pcm_SBA_128000_32-16_BinauralRoomReverb_Headrot_BinauralFile.tst // Planar SBA at 128 kbps, 48kHZ in, 32kHz out, BINAURAL_ROOM_REVERB out (Model from file), Config renderer, HR ../IVAS_cod -sba -1 128000 48 testv/ltv48_FOA.wav bit -../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/ltv48_FOA.pcm_planarSBA_12800032-32_BinauralRoomReverb_Config_renderer_Headrot_BinauralFile.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin -t testv/headrot_case00_3000_q.csv -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 32 bit testv/ltv48_FOA.pcm_planarSBA_128000_48-32_BinauralRoomReverb_Config_renderer_Headrot_BinauralFile.tst // SBA 3OA at 128 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB rendconf sel acoustic env ../IVAS_cod -sba 3 128000 48 testv/ltv48_HOA3.wav bit -../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1 BINAURAL_ROOM_REVERB 48 bit testv/ltv48_HOA3.pcm_SBA_12800048-48_BinauralRoomReverb_Config_renderer_combined_AEID_1.tst +../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1 BINAURAL_ROOM_REVERB 48 bit testv/ltv48_HOA3.pcm_SBA_128000_48-48_BinauralRoomReverb_Config_renderer_combined_AEID_1.tst // SBA at 256 kbps, 48kHz in, 48kHz out, PCA, BINAURAL out ../IVAS_cod -pca -sba 1 256000 48 testv/ltv48_FOA.wav bit ../IVAS_dec BINAURAL 48 bit testv/ltv48_FOA.wav_SBA_PCA_256000_48-48_BINAURAL.tst +// SBA FOA bitrate switching from 13.2 kbps to 192 kbps, 32kHz in, 32kHz out, DTX on, EXT out +../IVAS_cod -dtx -sba 1 ../scripts/switchPaths/sw_13k2_192k_50fr.bin 32 testv/ltv32_FOA.wav bit +../IVAS_dec EXT 32 bit testv/ltv32_FOA.wav_sw_32-32_DTX_EXT.tst + +// SBA 2OA bitrate switching from 13.2 kbps to 128 kbps, 32kHz in, 32kHz out, DTX on, EXT out +../IVAS_cod -dtx -sba 2 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 32 testv/ltv32_HOA2.wav bit +../IVAS_dec EXT 32 bit testv/ltv32_HOA2.wav_sw_32-32_DTX_EXT.tst + +// SBA 3OA bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, DTX on, random FER at 5%, EXT out +../IVAS_cod -dtx -sba 3 ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/ltv48_HOA3.wav bit +eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error +../IVAS_dec EXT 48 bit_error testv/ltv48_HOA3.wav_sw_48-48_DTX_EXT_FER5.tst + // MASA 1dir 1TC at 13.2 kbps, 48kHz in, 48kHz out, BINAURAL out, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_SWB.txt -masa 1 testv/ltv48_MASA1TC.met 13200 48 testv/ltv48_MASA1TC.wav bit @@ -1252,7 +1268,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // Multi-channel 7_1_4 at 160 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM_IR out, HR ../IVAS_cod -mc 7_1_4 160000 48 testv/ltv48_MC714.wav bit -../IVAS_dec -t testv/headrot.csv BINAURAL 48 bit testv/ltv48_MC714.wav_MC714_160000_48-48_MC_binaural_hrot.tst +../IVAS_dec -t testv/headrot.csv BINAURAL 16 bit testv/ltv48_MC714.wav_MC714_160000_48-16_MC_binaural_hrot.tst // Multi-channel 7_1_4 at 160 kbps, 48kHz in, 48kHz out, 7_1_4 out ../IVAS_cod -mc 7_1_4 160000 48 testv/ltv48_MC714.wav bit @@ -1283,7 +1299,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 7_1 512000 48 testv/ltv48_MC71.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC71.wav_MC71_512000_48-48_MC_Config_renderer.tst -// Multi-channel 5_1 at 80 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM_REVERB out Config renderer +// Multi-channel 5_1 at 80 kbps, 48kHz in, 32kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR ../IVAS_cod -mc 5_1 80000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg -t ../scripts/trajectories/full-circle-4s.csv BINAURAL_ROOM_REVERB 32 bit testv/ltv48_MC51.wav_MC51_80000_48-32_MC_Config_renderer.tst @@ -1299,7 +1315,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 160000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_recreation.cfg -t ../scripts/trajectories/full-circle-with-up-and-down-4s.csv BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_M714_160000_48-48_MC_Config_recreation.tst -// Multi-channel 5_1_2 64 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR +// Multi-channel 5_1_2 at 64 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config renderer, HR ../IVAS_cod -mc 5_1_2 64000 48 testv/ltv48_MC512.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg -t testv/headrot_case04_3000_q.csv BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC512.wav_MC512_64000_48-48_MC_Config_renderer.tst @@ -1319,7 +1335,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v2.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_ER_v2.tst -// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config early reflections, low complexity, listener origin +// Multi-channel 7_1_4 at 512 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Conf early refl, low complexity, listener origin ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -render_config testv/rend_config_ER_v3.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_ER_v3.tst @@ -1377,6 +1393,25 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 7_1_4 512000 48 testv/ltv48_MC714.wav bit ../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin BINAURAL_ROOM_IR 48 bit testv/ltv48_MC714.wav_MC714_512000_48-48_MC_binaural_room.tst +// Multi-channel 5_1 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, EXT out +../IVAS_cod -mc 5_1 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/ltv48_MC51.wav bit +../IVAS_dec HOA3 48 bit testv/ltv48_MC51.wav_sw_48-48_EXT.tst + +// Multi-channel 5_1_2 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, EXT out +../IVAS_cod -mc 5_1_2 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_MC512.wav bit +../IVAS_dec EXT 48 bit testv/ltv48_MC512.wav_sw_48-48_EXT.tst + +// Multi-channel 5_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 32kHz out, EXT out +../IVAS_cod -mc 5_1_4 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_MC514.wav bit +../IVAS_dec EXT 32 bit testv/ltv48_MC514.wav_sw_48-32_EXT.tst + +// Multi-channel 7_1 bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 16kHz out, EXT out +../IVAS_cod -mc 7_1 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/ltv48_MC71.wav bit +../IVAS_dec EXT 16 bit testv/ltv48_MC71.wav_sw_48-16_EXT.tst + +// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, EXT out +../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/ltv48_MC714.wav bit +../IVAS_dec EXT 48 bit testv/ltv48_MC714.wav_sw_48-48_EXT.tst // Stereo downmix to bit-exact EVS at 13200 kbps, 32kHz in, 32kHz out @@ -1725,15 +1760,15 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -ism_sba 4 3 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 32 testv/ltv32_OSBA_4ISM_HOA3.wav bit ../IVAS_dec EXT 48 bit testv/ltv32_OSBA_4ISM_HOA3.wav_EXT_sw_13k2_512k_32-32.tst -// OSBA FOA 4ISM at bitrate switching 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching +// OSBA FOA 4ISM at br sw 13.2 to 512 kbps, 48kHz in, 16kHz out, BINAURAL out (Model from file), FER at 5%, bandwidth switching ../IVAS_cod -max_band testv/ivas_bws_20fr_start_WB.txt -ism_sba 4 1 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv testv/ltvISM4.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_4ISM_FOA.wav bit eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g192 bit_error -../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit_error testv/ltv48_OSBA_4ISM_FOA.wav_BINAURAL_sw_48-48_FER5.tst +../IVAS_dec -hrtf ../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin BINAURAL 16 bit_error testv/ltv48_OSBA_4ISM_FOA.wav_BINAURAL_sw_48-16_FER5.tst // OSBA 3ISM 2OA at bitrate switching 13.2 to 512 kbps, 48kHz in, 32kHz out, STEREO out, FER at 10% -// ../IVAS_cod -ism_sba 3 2 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_3ISM_2OA.wav bit -// eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g192 bit_error -// ../IVAS_dec STEREO 32 bit_error testv/ltv48_OSBA_3ISM_2OA.wav_STEREO_sw_48-32_FER10.tst +../IVAS_cod -ism_sba 3 2 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_3ISM_HOA2.wav bit +eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_10pct.g192 bit_error +../IVAS_dec STEREO 32 bit_error testv/ltv48_OSBA_3ISM_2OA.wav_STEREO_sw_48-32_FER10.tst // OSBA 3ISM 3OA at bitrate switching 13.2 to 512 kbps, 48kHz in, 32kHz out, BINAURAL ROOM REVERB out ../IVAS_cod -ism_sba 3 3 testv/ltvISM1.csv testv/ltvISM2.csv testv/ltvISM3.csv ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/ltv48_OSBA_3ISM_HOA3.wav bit diff --git a/scripts/dec_isar_header.txt b/scripts/dec_isar_header.txt new file mode 100644 index 0000000000000000000000000000000000000000..454383382f916f091bebd25166b1dba9df32b651 --- /dev/null +++ b/scripts/dec_isar_header.txt @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit -1 +fi + +CUT_DEC_BIN=$1 +DIFF_BIN="diff" + +TESTV_PATH="." +REF_PATH="./testv" +CUT_PATH="./TMP_DEC_ISAR" +LOG_FILE=Readme_IVAS_ISAR_dec_log.txt + +rm -rf tmp +rm -rf $CUT_PATH +mkdir -p $CUT_PATH +mkdir -p $CUT_PATH/split_rendering/cut + + diff --git a/scripts/dly_error_profiles/dly_error_profile_10_smoke_test.dat b/scripts/dly_error_profiles/dly_error_profile_10_smoke_test.dat new file mode 100644 index 0000000000000000000000000000000000000000..fec3e67fbd515f337eb3b5e8f5019e2724e085e7 --- /dev/null +++ b/scripts/dly_error_profiles/dly_error_profile_10_smoke_test.dat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe29117bce3afc93b2c9ffdc38f930a2914dc9376f0386a9fcab95f0d0ee479c +size 188 diff --git a/scripts/isar_post_rend_header.txt b/scripts/isar_post_rend_header.txt new file mode 100644 index 0000000000000000000000000000000000000000..ed7eb2098866cbcbdcd8e3c4fc7c507ec3ba8415 --- /dev/null +++ b/scripts/isar_post_rend_header.txt @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit -1 +fi + +CUT_ISAR_POST_REND_BIN=$1 +DIFF_BIN="diff" + +TESTV_PATH="." +REF_PATH="./testv" +CUT_PATH="./TMP_ISAR_POST_REND" +LOG_FILE=Readme_IVAS_isar_post_rend_log.txt + +rm -rf tmp +rm -rf $CUT_PATH +mkdir -p $CUT_PATH/split_rendering/cut + + + diff --git a/scripts/lc3plus_lib_setup/get_lc3plus.sh b/scripts/lc3plus_lib_setup/get_lc3plus.sh index 71b2a722ba76247d9bf1f7f19e7ce70fd94c874e..ea2a893d1993fc2750a128ffdeb7b71f21033244 100755 --- a/scripts/lc3plus_lib_setup/get_lc3plus.sh +++ b/scripts/lc3plus_lib_setup/get_lc3plus.sh @@ -2,38 +2,64 @@ # This script shall only be used by automated continuous integration systems -scriptdir=$(dirname "$0") -pushd "$scriptdir" || exit 1 +printf "Cleaning old version of LC3plus\n" +rm -rf lib_lc3plus -# Download and unzip LC3plus code -rm -rf ETSI_Release -curl -o ./lc3plus_sources.zip https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.04.01_60/ts_103634v010401p0.zip -unzip lc3plus_sources.zip -d . - -# Modify LC3plus code to be compatible with IVAS tools (e.g. WMC tool) -git apply --ignore-whitespace lc3plus.patch -rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft.c -rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/codec_exe.c +printf "Downloading LC3plus code\n" +if false; then + # Waiting for official ETSI release. + # TODO: add new URL, remove `if false` when package goes public + curl -o ./lc3plus_sources.zip NEW_URL_HERE + unzip lc3plus_sources.zip -d . + rm lc3plus_sources.zip + cp -r "ETSI_Release//src/floating_point" lib_lc3plus + rm -r ETSI_Release +else + # Temp solution for downloading WIP ETSI package + # LC3_ETSI_REPO_URL must be define before running the script + git clone "$LC3_ETSI_REPO_URL" + cp -r lc3_etsi_release/src/floating_point lib_lc3plus + rm -rf lc3_etsi_release +fi # Remove unneeded files -rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/makefile -rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h -rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywaveout_c.h -rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c -rm -r ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc +printf "Removing unneeded files\n" +rm lib_lc3plus/codec_exe.c # Only used for executable +rm lib_lc3plus/makefile # Build handled at IVAS level +rm -r lib_lc3plus/msvc # Build handled at IVAS level +rm lib_lc3plus/plc_noise_substitution0.c # Empty file +rm lib_lc3plus/tinywavein_c.h # Only used for executable +rm lib_lc3plus/tinywaveout_c.h # Only used for executable # Limit file permissions -find ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point -type f -exec chmod -x {} \; - -# Move to output dir -rm -rf ../../lib_lc3plus -mkdir ../../lib_lc3plus -mv ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/* ../../lib_lc3plus +printf "Limiting file permissions\n" +find lib_lc3plus -type f -print0 | \ +xargs -0 -I {} \ +chmod -x {} -# Create additional files -printf "DisableFormat: true\nSortIncludes: Never\n" > ../../lib_lc3plus/.clang-format +# include options.h in all C files +printf "Including options.h and wmc_auto.h in C files\n" +find lib_lc3plus -name '*.[ch]' -type f -print0 | \ +xargs -0 -I {} \ +sed -i ' +# range: from 1st line to first match +1,/^#include/ { + # insert lines before first match + /^#include/ i\ +#include "options.h"\ +#include "wmc_auto.h" +} +' {} -# Clean up -rm -rf lc3plus_sources.zip ETSI_Release +# Remove whitespace from preprocessor commands +printf "Removing whitespace from preprocessor commands\n" +find lib_lc3plus -name '*.[ch]' -type f -print0 | \ +xargs -0 -I {} \ +sed -i 's/^#[[:space:]]\+/#/' {} -popd || exit +# Add .clang-format file to lib_lc3plus to disable formatting there +printf "Disabling clang-format in lib_lc3plus directory\n" +printf ' +DisableFormat: true +SortIncludes: Never +' >> lib_lc3plus/.clang-format diff --git a/scripts/lc3plus_lib_setup/lc3plus.patch b/scripts/lc3plus_lib_setup/lc3plus.patch deleted file mode 100644 index 14b81a39727b034b4d1de3b01a90879baeb34947..0000000000000000000000000000000000000000 --- a/scripts/lc3plus_lib_setup/lc3plus.patch +++ /dev/null @@ -1,1474 +0,0 @@ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "stdint.h" - #include - #include -@@ -1010,8 +1011,8 @@ - LC3_UINT8 blacklist[FEC_N_MODES]; - LC3_INT32 rop; - -- rop = 0; - void (*syndr_calc[3])(LC3_UINT8 *, LC3_UINT8 *, LC3_INT32); -+ rop = 0; - - /* initialization */ - blacklist[0] = 0; -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static void ac_shift_fl(Encoder_State_fl* st); -@@ -620,7 +621,7 @@ - - if (st.pc_c_bp_side != 0) - { -- nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOG2(mask_side)); -+ nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side)); - } - } - -@@ -891,7 +892,7 @@ - { - LC3_INT bits = 0, mask = 0, val = 0, over1 = 0, high = 0, over2 = 0, c = 0, b = 0; - -- bits = 24 - floor(LC3_LOG2(st->range)); -+ bits = 24 - floor(LC3_LOGTWO(st->range)); - mask = ((LC3_INT)pow(2, 24) - 1) >> bits; - val = st->low + mask; - over1 = val >> 24; -@@ -1078,8 +1079,8 @@ - } - - /* Residual bits */ -- nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOG2(*(st.mask_side))); -- nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOG2(st.range)); -+ nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOGTWO(*(st.mask_side))); -+ nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOGTWO(st.range)); - - if (st.cache >= 0) { - nbits_ari = nbits_ari + 8; -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - /* DCT */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void dct2_init(Dct2* dct, int length) -@@ -27,11 +28,11 @@ - - void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) - { -- assert(input != output); - Complex tmp1[MAX_LEN]; - Complex tmp2[MAX_LEN]; - int i = 0; - const int len = dct->length; -+ assert(input != output); - - for (i = 0; i < len / 2; i++) { - tmp1[i] = cmplx(input[i * 2], 0); -@@ -49,8 +50,8 @@ - - void dct4_init(Dct4* dct, int length) - { -- assert(length <= MAX_LEN); - int i = 0; -+ assert(length <= MAX_LEN); - dct->length = length; - dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); - dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); -@@ -73,12 +74,12 @@ - - void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) - { -- assert(input != output); - Complex tmp2[MAX_LEN / 2]; - int i = 0; - Complex* tmp1 = (Complex*)output; - const int len = dct->length; - const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); -+ assert(input != output); - - for (i = 0; i < len / 2; i++) { - tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); -@@ -53,7 +54,7 @@ - LC3_INT nbbytes = nbbits >> 3; - LC3_INT lastnz; - LC3_INT bw_cutoff_idx; -- LC3_INT nbits = ceil(LC3_LOG2(L_spec / 2)); -+ LC3_INT nbits = ceil(LC3_LOGTWO(L_spec / 2)); - - if (nbits > nbbits) - { -@@ -173,7 +174,7 @@ - } - - /* Last non-zero tuple */ -- read_uint_fl(ceil(LC3_LOG2(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); -+ read_uint_fl(ceil(LC3_LOGTWO(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); - *lastnz = (*lastnz + 1) * 2; - - if (*lastnz > N) { -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -@@ -53,8 +54,8 @@ - - if (decoder->rframe == 1 && zero_frame == 0 && bfi != 1) - { -- bfi = 2; - LC3_INT32 max_bw_stopband = BW_cutoff_bin_all[bw_cutoff_idx]; -+ bfi = 2; - switch (decoder->frame_dms) - { - # ifdef ENABLE_025_DMS_MODE -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h 2023-06-29 12:58:27 -@@ -24,13 +24,13 @@ - typedef uint32_t LC3_UINT32; - - /* Release defines */ --#define ENABLE_2_5MS_MODE -+// #define ENABLE_2_5MS_MODE - #define ENABLE_5MS_MODE - #define ENABLE_10_MS_MODE - #define ENABLE_ADVANCED_PLC_FL - #define ENABLE_ADVANCED_PLC_FL_DEFAULT - #define ENABLE_BW_CONTROLLER --#define ENABLE_HR_MODE_FL -+//#define ENABLE_HR_MODE_FL - #define ENABLE_PADDING - #define ENABLE_RFRAME_FL - #define ENABLE_PLC -@@ -49,8 +49,8 @@ - /* Precision Defines */ - #define LC3_FABS(x) (fabsf(x)) - #define LC3_POW(x, y) (powf(x, y)) --#define LC3_LOG10(x) (log10f(x)) --#define LC3_LOG2(x) (log2f(x)) -+#define LC3_LOGTEN(x) (log10f(x)) -+#define LC3_LOGTWO(x) (log2f(x)) - # define LC3_COS(x) (cos(x)) - # define LC3_SIN(x) (sin(x)) - #define LC3_SQRT(x) (sqrtf(x)) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) -@@ -68,7 +69,7 @@ - dist = bw_dist[counter]; - - for (i = stop; i >= stop - dist; i--) { -- e_diff = 10.0 * LC3_LOG10(d2[i - dist + 1] + FLT_EPSILON) - 10.0 * LC3_LOG10(d2[i + 1] + FLT_EPSILON); -+ e_diff = 10.0 * LC3_LOGTEN(d2[i - dist + 1] + FLT_EPSILON) - 10.0 * LC3_LOGTEN(d2[i + 1] + FLT_EPSILON); - - if (e_diff > thr) { - brickwall = 1; -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, -@@ -33,11 +34,11 @@ - - /* Last non zero touple */ - if (bfi_ext == 1) { -- write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOG2(N >> 1))); -+ write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOGTWO(N >> 1))); - } - else - { -- write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOG2(N / 2))); -+ write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N / 2))); - } - - /* LSB mode bit */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -@@ -60,8 +61,8 @@ - } else { - g_min = x_max / (32767 - 0.375); - } -- /* Prevent positive rounding errors from LC3_LOG10 function */ -- ind_min = 28.0 * LC3_LOG10(g_min); -+ /* Prevent positive rounding errors from LC3_LOGTEN function */ -+ ind_min = 28.0 * LC3_LOGTEN(g_min); - - ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS); - -@@ -76,7 +77,7 @@ - tmp += x[i + 1] * x[i + 1]; - tmp += x[i + 2] * x[i + 2]; - tmp += x[i + 3] * x[i + 3]; -- en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOG10(tmp + reg_val)); -+ en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val)); - j++; - } - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c 2023-06-29 12:58:27 -@@ -8,7 +8,7 @@ - ******************************************************************************/ - - -- -+#include "options.h" - #include "cfft.h" - #include "iisfft.h" /* for M_PIl */ - #include /* for abs() */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c 2023-06-29 12:58:27 -@@ -8,14 +8,15 @@ - ******************************************************************************/ - - -+#include "options.h" - #include - #include --#include "iis_fft.h" - #include - #include - #include --#include "../structs.h" -+#include - -+#include "iis_fft.h" - /**************************************************************************************************/ - - /* AFFT uses two fft implementations -@@ -24,9 +25,6 @@ - fast lengths, check the fft_n function. - */ - --#include --#include "cfft.h" --#include "iisfft.h" - - #define FFT_COMPLEX 1 - #define FFT_REAL 2 -@@ -122,12 +120,13 @@ - - IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output) - { -+ LC3_FLOAT* dummy; - if (!handle) - return IIS_FFT_INTERNAL_ERROR; - - /* check for inplace operation */ - memmove(output, input, sizeof(*input) * handle->len); -- LC3_FLOAT* dummy = (LC3_FLOAT*)output; -+ dummy = (LC3_FLOAT*)output; - if (handle->cfft.len > 0) { - LC3_cfft_apply(&handle->cfft, dummy, dummy + 1, 2); - } else { -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h 2023-06-29 12:58:27 -@@ -12,6 +12,7 @@ - #define IIS_FFT_H - - #include "../structs.h" -+#include "../defines.h" - #include "cfft.h" - - #ifdef __cplusplus -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - - #include - #include /* for mmove */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h 2023-06-29 12:58:27 -@@ -11,6 +11,7 @@ - #ifndef IISFFT_H - #define IISFFT_H - -+#include "../defines.h" - - #ifndef M_PIl - #define M_PIl 3.1415926535897932384626433832795029L /* pi */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - /* Function expects already flipped window */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "lc3.h" - #include "defines.h" - #include "functions.h" -@@ -48,8 +49,9 @@ - case 44100: return 1; - case 48000: return 1; - case 96000: return 1; -- default: return 0; -+ default: break; - } -+ return 0; - } - - static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) -@@ -58,8 +60,9 @@ - { - case LC3PLUS_PLC_ADVANCED: /* fallthru */ - return 1; -- default: return 0; -+ default: break; - } -+ return 0; - } - - static int lc3plus_frame_size_supported(float frame_ms) -@@ -69,8 +72,9 @@ - case 25: /* fallthru */ - case 50: /* fallthru */ - case 100: return 1; -- default: return 0; -+ default: break; - } -+ return 0; - } - - static int null_in_list(void **list, int n) -@@ -97,13 +101,14 @@ - /* encoder functions *********************************************************/ - LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]) - { -+ int ch = 0; -+ - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); - RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR); - RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); - RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); - RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); - -- int ch = 0; - for (ch = 0; ch < channels; ch++) - { - RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); -@@ -142,6 +147,7 @@ - int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) - { - int ch = 0, totalBytes = 0; -+ int bitrate; - RETURN_IF(encoder == NULL, 0); - RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); - -@@ -150,7 +156,7 @@ - totalBytes += encoder->channel_setup[ch]->targetBytes; - } - -- int bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; -+ bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; - - if (encoder->fs_in == 44100) - { -@@ -191,11 +197,13 @@ - - LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) - { -+ LC3_INT effective_fs; -+ - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); - #ifdef ENABLE_HR_MODE_FL_FLAG - RETURN_IF(encoder->hrmode == 1, LC3PLUS_HRMODE_BW_ERROR); - #endif -- LC3_INT effective_fs = encoder->fs_in; -+ effective_fs = encoder->fs_in; - if (encoder->bandwidth != bandwidth) { - if (encoder->fs_in > 40000) { - effective_fs = 40000; -@@ -338,9 +346,9 @@ - - LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) - { -+ int ch = 0; - RETURN_IF(!encoder, LC3PLUS_NULL_ERROR); - -- int ch = 0; - for (ch = 0; ch < encoder->channels; ch++) { - mdct_free(&encoder->channel_setup[ch]->mdctStruct); - dct2_free(&encoder->channel_setup[ch]->dct2StructSNS); -@@ -351,9 +359,9 @@ - - LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) - { -+ int ch = 0; - RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); - -- int ch = 0; - for (ch = 0; ch < decoder->channels; ch++) { - dct4_free(&decoder->channel_setup[ch]->dct4structImdct); - real_fft_free(&decoder->channel_setup[ch]->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft); -@@ -378,11 +386,14 @@ - - LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) - { -+ LC3PLUS_EpMode oldEpmode; -+ LC3PLUS_Error error; -+ - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); - RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); -- LC3PLUS_EpMode oldEpmode = encoder->epmode; -+ oldEpmode = encoder->epmode; - encoder->epmode = epmode; -- LC3PLUS_Error error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; -+ error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; - if (error != LC3PLUS_OK) - { - encoder->epmode = oldEpmode; // preserve old epmode in case of failure -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c 1970-01-01 01:00:00 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c 2023-06-29 12:58:27 -@@ -0,0 +1,99 @@ -+/****************************************************************************** -+* ETSI TS 103 634 V1.4.1 * -+* Low Complexity Communication Codec Plus (LC3plus) * -+* * -+* Copyright licence is solely granted through ETSI Intellectual Property * -+* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * -+* estoppel or otherwise. * -+******************************************************************************/ -+ -+ -+#include "options.h" -+#include "functions.h" -+#include "fft/iis_fft.c" -+#include "fft/iisfft.c" -+#include "fft/cfft.c" -+ -+void fft_init(Fft* fft, int length) -+{ -+ HANDLE_IIS_FFT handle = NULL; -+ IIS_FFT_ERROR error = 0; -+ assert(length % 2 == 0); -+ -+ fft->length = length; -+ -+ error = LC3_IIS_CFFT_Create(&handle, length, IIS_FFT_FWD); -+ -+ assert(error == IIS_FFT_NO_ERROR); -+ fft->handle = handle; -+} -+ -+void fft_free(Fft* fft) -+{ -+ IIS_FFT_ERROR error = 0; -+ -+ if (fft) { -+ error = LC3_IIS_CFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); -+ -+ assert(error == IIS_FFT_NO_ERROR); -+ memset(fft, 0, sizeof(*fft)); -+ } -+} -+ -+void real_fft_free(Fft* fft) -+{ -+ IIS_FFT_ERROR error = 0; -+ -+ if (fft) { -+ error = LC3_IIS_RFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); -+ -+ assert(error == IIS_FFT_NO_ERROR); -+ memset(fft, 0, sizeof(*fft)); -+ } -+} -+ -+void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) -+{ -+ IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; -+ assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ -+ -+ fft->length = length; -+ -+ error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_FWD); -+ assert(error == IIS_FFT_NO_ERROR); -+ fft->handle = *handle; -+} -+ -+ -+void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) -+{ -+ IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; -+ assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ -+ -+ fft->length = length; -+ -+ error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_BWD); -+ -+ assert(error == IIS_FFT_NO_ERROR); -+ fft->handle = *handle; -+} -+ -+void fft_apply(Fft* fft, const Complex* input, Complex* output) -+{ -+ IIS_FFT_ERROR error = 0; -+ error = LC3_IIS_FFT_Apply_CFFT(fft->handle, input, output); -+ -+ assert(error == IIS_FFT_NO_ERROR); -+} -+ -+ -+void real_fft_apply(Fft* fft, const LC3_FLOAT* input, LC3_FLOAT* output) -+{ -+ IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; -+ -+ UNUSED(error); -+ -+ error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); -+ -+ assert(error == IIS_FFT_NO_ERROR); -+} -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) -@@ -104,6 +105,7 @@ - { - LC3_FLOAT tmp[MAX_LEN * 2] = {0}; - LC3_INT i = 0; -+ LC3_INT hlen; - - move_float(tmp, mdct->mem, mdct->mem_length); - move_float(tmp + mdct->mem_length, input, mdct->length); -@@ -112,7 +114,7 @@ - - mult_vec(tmp, mdct->window, mdct->length * 2); - -- LC3_INT hlen = mdct->length / 2; -+ hlen = mdct->length / 2; - for (i = 0; i < hlen; i++) { - output[i] = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i]; - output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1]; -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore 1970-01-01 01:00:00 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore 2023-06-29 12:58:27 -@@ -0,0 +1 @@ -+Win32/ -\ No newline at end of file -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c 2023-06-29 12:58:35 -@@ -8,15 +8,16 @@ - ******************************************************************************/ - - #include "functions.h" -+#include "options.h" - - - void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener) - { - *near_nyquist_flag = 0; -- -+ - if (fs_idx < 4) -- { -+ { - LC3_INT i = 0; - LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, -@@ -56,6 +57,8 @@ - { - case 2: - { -+ LC3_FLOAT pitch_fl_c; -+ - assert(decoder->fs_idx == floor(decoder->fs / 10000)); - // phaseECU supports only 10ms framing - assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100); -@@ -69,7 +72,7 @@ - } - - /* call phaseEcu */ -- LC3_FLOAT pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */ -+ pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */ - - - if (prev_bfi_plc2 == 0) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -@@ -135,13 +136,13 @@ - - if (max_xfp_abs >= 0.5) - { -- PLC2_Q_flt = (LC3_FLOAT)LC3_FLOOR(LC3_LOG2(32768 / 2 / 2 / max_xfp_abs)); -+ PLC2_Q_flt = (LC3_FLOAT)LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / max_xfp_abs)); - Q_scale_flt = LC3_POW(2.0, PLC2_Q_flt) / fx_fft_scale / fft_fs_scale; /* basop way using xfp scale */ - - /* C-Float additional safety limit/verification of the integer xfp based scaling using the available C-float Xabs max value inp_high as well */ - { - LC3_FLOAT tmp_scale; -- tmp_scale = LC3_POW(2.0, LC3_FLOOR(LC3_LOG2(32768 / 2 / 2 / inp_high))); -+ tmp_scale = LC3_POW(2.0, LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / inp_high))); - if (Q_scale_flt > tmp_scale) { - Q_scale_flt = tmp_scale; - } -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - #include "constants.h" -@@ -30,6 +31,7 @@ - LC3_INT32 segmentLen, e; - LC3_FLOAT Xph; - LC3_FLOAT seed_local; -+ LC3_INT32 binCounter, subInd; - - UNUSED(corr_phase_dbg); - UNUSED(X_i_new_re_dbg); -@@ -49,8 +51,8 @@ - - - // EVOLVE PHASE ----------------- -- LC3_INT32 binCounter = 1; -- LC3_INT32 subInd = 0; -+ binCounter = 1; -+ subInd = 0; - - one_peak_flag_mask = -1; - if (n_plocs < 3 && n_plocs > 0) { -@@ -219,9 +221,10 @@ - } - - static LC3_INT32 own_rand(LC3_INT32 seed) { -- assert(seed <= 32767 && seed >= -32768); -- LC3_INT32 retSeed = (13849 + (seed + 32768) * 31821) & 65535; -- retSeed -= 32768; -+ LC3_INT32 retSeed; -+ assert(seed <= 32767 && seed >= -32768); -+ retSeed = (13849 + (seed + 32768) * 31821) & 65535; -+ retSeed -= 32768; - assert(retSeed <= 32767 && retSeed >= -32768); - return retSeed; - } -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c 2023-06-29 12:58:35 -@@ -6,13 +6,14 @@ - * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * - * estoppel or otherwise. * - ******************************************************************************/ -- - -+ -+#include "options.h" - #include "defines.h" - #include "functions.h" - - --void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) -+void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) - { - LC3_INT32 i; - -@@ -34,10 +35,10 @@ - trans[i] = 1.0; /* 0/0 no transient , no power change */ - } - } -- grp_pow_change[i] = (LC3_FLOAT) 10.0 * LC3_LOG10(trans[i]); -+ grp_pow_change[i] = (LC3_FLOAT) 10.0 * LC3_LOGTEN(trans[i]); - - } - -- return; -+ return; - } - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "defines.h" - #include "functions.h" - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c 2023-06-29 12:58:35 -@@ -6,16 +6,17 @@ - * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * - * estoppel or otherwise. * - ******************************************************************************/ -- - -+ -+#include "options.h" - #include "defines.h" - #include "functions.h" - - --void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, -- LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, -+void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, -+ LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, - LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, -- LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg) -+ LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg) - { - LC3_FLOAT gr_pow_left[MAX_LGW]; - LC3_FLOAT gr_pow_right[MAX_LGW]; -@@ -27,7 +28,7 @@ - - LC3_INT32 attDegreeFrames; - LC3_FLOAT thresh_dbg; -- -+ - UNUSED(tr_dec_dbg); - UNUSED(gpc_dbg); - -@@ -39,7 +40,7 @@ - - } - -- -+ - plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg); - - return; -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - /***************************************************************************\ - * contents/description: Main function for Time domain concealment - \***************************************************************************/ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - #include "functions.h" -+#include "options.h" - - - void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static LC3_INT sign(LC3_FLOAT x); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], -@@ -17,6 +18,8 @@ - - LC3_INT len_12k8 = 0, N12k8 = 0, i = 0, k = 0; - LC3_FLOAT mac = 0, buf_out[120 + MAX_LEN] = {0}, bufdown[128] = {0}, buf[120 + MAX_LEN] = {0}; -+ LC3_INT32 index_int, index_frac, resamp_upfac, resamp_delay, resamp_off_int, resamp_off_frac; -+ LC3_FLOAT u_11, u_21, u_1, u_2; - - const LC3_FLOAT *filter; - const LC3_FLOAT *filt_input, *filt_coeff; -@@ -49,12 +52,12 @@ - - /* Upsampling & Low-pass Filtering & Downsampling */ - -- LC3_INT32 index_int = 1; -- LC3_INT32 index_frac = 0; -- LC3_INT32 resamp_upfac = resamp_params[fs_idx][0]; -- LC3_INT32 resamp_delay = resamp_params[fs_idx][1]; -- LC3_INT32 resamp_off_int = resamp_params[fs_idx][2]; -- LC3_INT32 resamp_off_frac = resamp_params[fs_idx][3]; -+ index_int = 1; -+ index_frac = 0; -+ resamp_upfac = resamp_params[fs_idx][0]; -+ resamp_delay = resamp_params[fs_idx][1]; -+ resamp_off_int = resamp_params[fs_idx][2]; -+ resamp_off_frac = resamp_params[fs_idx][3]; - - k = 0; - for (i = 0; i < N12k8; i++) { -@@ -78,9 +81,8 @@ - - - /* 50Hz High-Pass */ -- LC3_FLOAT u_11 = mem_50[0]; -- LC3_FLOAT u_21 = mem_50[1]; -- LC3_FLOAT u_1, u_2; -+ u_11 = mem_50[0]; -+ u_21 = mem_50[1]; - - for (i = 0; i < len_12k8; i++) { - LC3_FLOAT y1 = (highpass50_filt_b[0] * bufdown[i] + u_11); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - #include "functions.h" -+#include "options.h" - - LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) - { -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "setup_dec_lc3.h" - #include "functions.h" - #include -@@ -32,6 +33,7 @@ - LC3_FLOAT *sine_table1_phecu, *sine_table2_phecu; - HANDLE_IIS_FFT handle_fft_phaseecu; - HANDLE_IIS_FFT handle_ifft_phaseecu; -+ LC3_FLOAT *q_old_res; - - for (ch = 0; ch < channels; ch++) { - DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); -@@ -56,7 +58,7 @@ - sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); - sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); - -- LC3_FLOAT *q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); -+ q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); - - if (decoder) { - decoder->channel_setup[ch] = setup; -@@ -346,6 +348,7 @@ - LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) - { - int totalBits = 0, bitsTmp = 0, channel_bytes = 0, maxBytes = 0, minBytes = 0; -+ DecSetup* setup; - - if (decoder->hrmode) - { -@@ -375,7 +378,7 @@ - - channel_bytes = nBytes; - -- DecSetup* setup = decoder->channel_setup[ch]; -+ setup = decoder->channel_setup[ch]; - - if (channel_bytes < minBytes || channel_bytes > maxBytes) - { -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "setup_enc_lc3.h" - #include "functions.h" - #include -@@ -33,6 +34,7 @@ - , int32_t lfe_channel_array[] - ) - { -+ int ch = 0; - memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels)); - alloc_encoder(encoder, channels); - -@@ -56,7 +58,6 @@ - encoder->r12k8_mem_in_len = 2 * 8 * encoder->fs / 12800; - encoder->r12k8_mem_out_len = 24; - -- int ch = 0; - for (ch = 0; ch < encoder->channels; ch++) - { - encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; -@@ -220,6 +221,7 @@ - - if (encoder->hrmode) - { -+#ifdef ENABLE_HR_MODE_FL - switch (encoder->frame_dms) - { - case 25: -@@ -243,6 +245,7 @@ - default: - return LC3PLUS_HRMODE_ERROR; - } -+#endif - } - else - { -@@ -368,7 +371,7 @@ - setup->total_bits = setup->targetBytes << 3; - setup->targetBitsInit = setup->total_bits - encoder->envelope_bits - encoder->global_gain_bits - - encoder->noise_fac_bits - encoder->BW_cutoff_bits - -- ceil(LC3_LOG2(encoder->frame_length / 2)) - 2 - 1; -+ ceil(LC3_LOGTWO(encoder->frame_length / 2)) - 2 - 1; - - if (setup->total_bits > 1280) { - setup->targetBitsInit = setup->targetBitsInit - 1; -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor) -@@ -109,7 +110,7 @@ - - /* Log-domain */ - for (i = 0; i < 64; i++) { -- xl[i] = LC3_LOG2(x[i]) / 2.0; -+ xl[i] = LC3_LOGTWO(x[i]) / 2.0; - } - - /* Downsampling */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h 2023-06-29 12:58:27 -@@ -17,6 +17,7 @@ - #include - #include - -+ - #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(__arm__) || \ - defined(__aarch64__) - #define __TWI_LE /* _T_iny _W_ave _I_n _L_ittle _E_ndian */ -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); -diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c ---- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c 2023-02-28 20:25:37 -+++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c 2023-06-29 12:58:27 -@@ -8,6 +8,7 @@ - ******************************************************************************/ - - -+#include "options.h" - #include "functions.h" - - void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) diff --git a/scripts/parse_commands.py b/scripts/parse_commands.py index fe1a1840ade2291536a596d1fd137d9c610445a2..3a5fb6c1afbda1a07593b1c5a3e1c7867490fe00 100644 --- a/scripts/parse_commands.py +++ b/scripts/parse_commands.py @@ -24,6 +24,7 @@ if __name__ == '__main__': cmds_enc=[] cmds_dec=[] cmds_rend=[] + cmds_isar_post_rend=[] if path.isdir(input): @@ -37,6 +38,45 @@ if __name__ == '__main__': cmds_enc.extend(re.findall(r"DUT encoder command:\\n\\t(.*?)\\n", line)) cmds_dec.extend(re.findall(r"DUT decoder command:\\n\\t(.*?)\\n", line)) cmds_rend.extend(re.findall(r"Running command\\n(.*?)\\n", line)) + cmds_isar_post_rend.extend(re.findall(r"Running ISAR post renderer command\\n(.*?)\\n", line)) + + # If pytest-html < v4 is used, the parsing will fail and render empty lists. This is a work-around in case that happens. + if all(not x for x in [cmds_enc, cmds_dec, cmds_rend, cmds_isar_post_rend]): + for html_report in input: + with open(html_report,'r') as infile: + enc_cmd = False + dec_cmd = False + rend_cmd = False + isar_post_rend_cmd = False + for line in infile.readlines(): + line = line.split("
    ")[0] # Remove trailing html tags + if enc_cmd: + cmds_enc.append(line) + enc_cmd = False + elif dec_cmd: + cmds_dec.append(line) + dec_cmd = False + elif rend_cmd: + cmds_rend.append(line) + rend_cmd = False + elif isar_post_rend_cmd: + cmds_isar_post_rend.append(line) + isar_post_rend_cmd = False + else: + if "DUT encoder command" in line: + enc_cmd = True + elif "DUT decoder command" in line: + dec_cmd = True + elif "Running command" in line: + rend_cmd = True + elif "Running ISAR post renderer command" in line: + isar_post_rend_cmd = True + + # Sort lists to keep deterministic order between runs + cmds_enc.sort() + cmds_dec.sort() + cmds_rend.sort() + cmds_isar_post_rend.sort() with open(txt_file.replace('.','_enc.'),'w', newline='\n') as outfile: with open('scripts/enc_header.txt','r') as header: @@ -60,11 +100,13 @@ if __name__ == '__main__': with open('scripts/script_footer.txt','r') as footer: outfile.write(footer.read()) - with open(txt_file.replace('.','_dec.'),'w', newline='\n') as outfile_dec, open(txt_file.replace('.','_JBM_dec.'),'w', newline='\n') as outfile_jbm: + with open(txt_file.replace('.','_dec.'),'w', newline='\n') as outfile_dec, open(txt_file.replace('.','_JBM_dec.'),'w', newline='\n') as outfile_jbm, open(txt_file.replace('.','_ISAR_dec.'),'w', newline='\n') as outfile_isar: with open('scripts/dec_header.txt','r') as header: outfile_dec.write(header.read()) with open('scripts/jbm_header.txt','r') as header: outfile_jbm.write(header.read()) + with open('scripts/dec_isar_header.txt','r') as header: + outfile_isar.write(header.read()) for cmd in cmds_dec: absolute_out = re.search(r"\s(([\S]+)(.wav))$", cmd) @@ -76,20 +118,29 @@ if __name__ == '__main__': arg = re.sub('IVAS_dec(.exe)?', '$CUT_DEC_BIN', arg) arg = re.sub('scripts', TESTV_PATH, arg) arg = re.sub('tests/ref', REF_PATH + r'/ref', arg) # For .fer cases the bitstream is in ref + arg = re.sub('tests/split_rendering/renderer_configs', REF_PATH + r'/split_rendering/renderer_configs', arg) + if re.search("^tests.*192$",arg): + arg = re.sub('tests/split_rendering/cut', REF_PATH + r'/split_rendering/ref', arg) if re.search("\.wav$",arg): arg = re.sub('tests', CUT_PATH, arg) # Output argument for decoder ends with .wav else: arg = re.sub('tests/dut', REF_PATH + r'/ref', arg) # Input argument + if re.search("^tests.*bit$",arg): + arg = re.sub('tests', CUT_PATH, arg) # Output argument for decoder ends with .wav args.append(arg) cmd = ' '.join(args) if 'VOIP' in cmd: outfile = outfile_jbm + elif 'BINAURAL_SPLIT' in cmd: + outfile = outfile_isar else: outfile = outfile_dec outfile.write(cmd+'\n') out = re.search(r"\s(([\S]+)(.wav))$", cmd) + isar_out = re.search(r"\s(([\S]+)(.bit))$", cmd) + isar_md_out = re.search(r"-om\s(([\S]+)(.bit))", cmd) if out: diff_cmds=[] for output in glob.glob(absolute_out.group(1) + '*'): @@ -97,11 +148,19 @@ if __name__ == '__main__': output = re.sub('tests', CUT_PATH, output) diff_cmds.append('$DIFF_BIN '+output.replace(CUT_PATH + r'/dut',REF_PATH + r'/ref')+' '+output+' >> $LOG_FILE 2>&1') outfile.write(('; ').join(diff_cmds)) + if isar_out and "cut" in isar_out.group(1): + outfile.write('$DIFF_BIN '+isar_out.group(1).replace(CUT_PATH + r'/split_rendering/cut',REF_PATH + r'/split_rendering/ref')+' '+isar_out.group(1)+' >> $LOG_FILE 2>&1') + if isar_md_out and "cut" in isar_md_out.group(1): + outfile.write('; $DIFF_BIN '+isar_md_out.group(1).replace(CUT_PATH + r'/split_rendering/cut',REF_PATH + r'/split_rendering/ref')+' '+isar_md_out.group(1)+' >> $LOG_FILE 2>&1\n') + else: + outfile.write('\n') outfile.write('\n\n') with open('scripts/script_footer.txt','r') as footer: outfile_dec.write(footer.read()) footer.seek(0) outfile_jbm.write(footer.read()) + footer.seek(0) + outfile_isar.write(footer.read()) with open(txt_file.replace('.','_rend.'),'w', newline='\n') as outfile: with open('scripts/rend_header.txt','r') as header: @@ -126,4 +185,30 @@ if __name__ == '__main__': outfile.write('$DIFF_BIN '+out.group(1).replace(CUT_PATH + r'/renderer/cut',REF_PATH + r'/renderer/ref')+' '+out.group(1)+' >> $LOG_FILE 2>&1\n') outfile.write('\n') with open('scripts/script_footer.txt','r') as footer: - outfile.write(footer.read()) \ No newline at end of file + outfile.write(footer.read()) + + with open(txt_file.replace('.','_ISAR_post_rend.'),'w', newline='\n') as outfile: + with open('scripts/isar_post_rend_header.txt','r') as header: + outfile.write(header.read()) + for cmd in cmds_isar_post_rend: + args = [] + for arg in cmd.split(): + # Adjust file arguments, pass other arguments as they are + if path.exists(arg): + arg = path.relpath(arg).replace('\\','/') + arg = re.sub('ISAR_post_rend(.exe)?', '$CUT_ISAR_POST_REND_BIN', arg) + arg = re.sub('scripts', TESTV_PATH, arg) + if re.search("^tests.*bit$",arg): + arg = re.sub('tests/split_rendering/cut', REF_PATH + r'/split_rendering/ref', arg) + arg = re.sub('tests', CUT_PATH, arg) + args.append(arg) + cmd = ' '.join(args) + + if "cut" in cmd: + outfile.write(cmd+'\n') + out = re.search(r"-o\s(([\S]+)(.wav|.raw|.pcm))", cmd) + if out and "cut" in out.group(1): + outfile.write('$DIFF_BIN '+out.group(1).replace(CUT_PATH + r'/split_rendering/cut',REF_PATH + r'/split_rendering/ref')+' '+out.group(1)+' >> $LOG_FILE 2>&1\n') + outfile.write('\n') + with open('scripts/script_footer.txt','r') as footer: + outfile.write(footer.read()) \ No newline at end of file diff --git a/scripts/parse_complexity_tables.py b/scripts/parse_complexity_tables.py new file mode 100644 index 0000000000000000000000000000000000000000..e87e3b05fa54445aae75290ae2ec40dd980110e7 --- /dev/null +++ b/scripts/parse_complexity_tables.py @@ -0,0 +1,780 @@ +#!/usr/bin/env python3 + +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +# contributors to this repository. All Rights Reserved. + +# This software is protected by copyright law and by international treaties. +# The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +# Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +# Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +# Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +# contributors to this repository retain full ownership rights in their respective contributions in +# the software. This notice grants no license of any kind, including but not limited to patent +# license, nor is any license granted by implication, estoppel or otherwise. + +# Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +# contributions. + +# This software is provided "AS IS", without any express or implied warranties. The software is in the +# development stage. It is intended exclusively for experts who have experience with such software and +# solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +# and fitness for a particular purpose are hereby disclaimed and excluded. + +# Any dispute, controversy or claim arising under or in relation to providing this software shall be +# submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +# accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +# the United Nations Convention on Contracts on the International Sales of Goods. + +""" + parse_complexity_tables.py + + A script to parse complexity tables from smoke_test_complexity.sh run + and collecting the results into an Excel and csv files. + + Arguments: + -input_tables_base: Paths to input tables base csv files (before the WMOPS etc. tags), separated by ';'. E.g., path/to/file1.csv;path/to/file_xyz_ (where the actual files are file_xyz_WMOPS.csv or file_xyz_TROM.csv, for example) + Optional. If not present, use the default paths inside this script. + + -output_table: Path to output table csv file, a complementary .xlsx file is also created. E.g., path/to/output_file.csv + Optional. If not present, use the default output path inside this script (default output directory is complexity_tables/). + + -input_limiters: List of input format limiters, separated by ';'. Optional, accepted values: + mono + foa + hoa2 + hoa3 + planar foa + planar hoa2 + planar hoa3 + masa 1tc + masa 2tc + mc 5_1 + mc 5_1_2 + mc 5_1_4 + mc 7_1 + mc 7_1_4 + stereo + stereodmxevs + omasa ism1 1tc + omasa ism1 2tc + omasa ism2 1tc + omasa ism2 2tc + omasa ism3 1tc + omasa ism3 2tc + omasa ism4 1tc + omasa ism4 2tc + osba ism1 foa + osba ism1 hoa2 + osba ism1 hoa3 + osba ism2 foa + osba ism2 hoa2 + osba ism2 hoa3 + osba ism3 foa + osba ism3 hoa2 + osba ism3 hoa3 + osba ism4 foa + osba ism4 hoa2 + osba ism4 hoa3 + ism1 + ism2 + ism3 + ism4 + ism+1 + ism+2 + ism+3 + ism+4 + + -bitrate_limiters: List of bitrate limiters, separated by ';'. Optional, accepted values: + EVS only: + 5.9 + 6.6 + 7.2 + 8.0 + 8.8 + 9.6 + 12.6 + 14.2 + 15.8 + 18.2 + 19.8 + 23.0 + + IVAS (and some EVS): + 13.2 + 16.4 + 24.4 + 32 + 48 + 64 + 80 + 96 + 128 + 160 + 192 + 256 + 384 + 512 + + -codec_mode_limiters: List of codec mode limiters, separated by ';'. Optional, accepted values: + EVS only: + amr + rf lo2 + rf lo3 + rf lo5 + rf lo7 + rf hi2 + rf hi3 + rf hi5 + rf hi7 + + IVAS and EVS: + dtx + non-dtx + rs + + Note: if 'non-dtx' is selected, all the dtx modes are discarded. + + -bandwidth_limiters: List of bandwidth limiters, separated by ';'. Optional, accepted values: + nb (EVS only) + wb + swb + fb + + -output_limiters: List of output format limiters, separated by ';'. Optional, accepted values: + mono + stereo + binaural + binaural_room_ir + binaural_room_reverb + foa + hoa2 + hoa3 + 5_1 + 5_1_2 + 5_1_4 + 7_1 + 7_1_4 + ext + + -profiler_limiters: Limit the included profiler analysis (e.g. WMOPS), separated by ';'. Optional, accepted values: + HEAP_INTRA + HEAP + PROM + RAM + STACK + TROM + WMOPS + +Output (as per default output table names): + combined_table_PROFILE.xlsx / .csv - contains all data in one file (PROFILE indicates the used profiler_limiters or ALL for all profiles included) + combined_table_INPUT_FORMAT.xlsx / .csv - contains all data for a single input format + heatmap_table_OUTPUT_FORMAT.xlsx - contains heatmap data for a single output format + max_input_PROFILE.xlsx / .csv - contains maximum complexity (and the respective codec configurations) per input format + combined_table_PROFILE.json - contains all data in one json file + +Note: the limiter arguments are used to narrow down the output table. For example, <-input_limiters "mono;stereo"> +would include only table values with mono and stereo input formats in the output table. +""" + +import argparse +import csv +import os +import openpyxl +import json +import copy + +def parse_configuration(row, profile): + # Parse e.g. + split_at = row.split("@") + input_mode = split_at[0].strip() + split_kbps = split_at[1].split("kbps") + bitrate = split_kbps[0].strip() + split_to = split_kbps[1].split("to") + codec_mode_bandwidth = split_to[0].strip().split(" ") + bandwidth = codec_mode_bandwidth[-1].strip() + separator = " " + codec_mode_list = codec_mode_bandwidth[0:-1] + codec_mode = separator.join(codec_mode_list) + split_dots = split_to[1].split(";") + output_mode = split_dots[0].strip() + + # Profile specific values + if profile.upper() == "HEAP_INTRA": + encoder_heap_intra = split_dots[1].strip() + decoder_heap_intra = split_dots[2].strip() + total_heap_intra = split_dots[3].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_heap_intra, decoder_heap_intra, total_heap_intra] + + elif profile.upper() == "HEAP": + encoder_heap = split_dots[1].strip() + decoder_heap = split_dots[2].strip() + total_heap = split_dots[3].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_heap, decoder_heap, total_heap] + + elif profile.upper() == "PROM": + encoder_prom = split_dots[1].strip() + decoder_prom = split_dots[2].strip() + com_prom = split_dots[3].strip() + rend_prom = split_dots[4].strip() + total_prom = split_dots[5].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_prom, decoder_prom, com_prom, rend_prom, total_prom] + + elif profile.upper() == "RAM": + encoder_ram = split_dots[1].strip() + decoder_ram = split_dots[2].strip() + total_ram = split_dots[3].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_ram, decoder_ram, total_ram] + + elif profile.upper() == "STACK": + encoder_stack = split_dots[1].strip() + decoder_stack = split_dots[2].strip() + max_stack = split_dots[3].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_stack, decoder_stack, max_stack] + + elif profile.upper() == "TROM": + encoder_trom = split_dots[1].strip() + decoder_trom = split_dots[2].strip() + com_trom = split_dots[3].strip() + rend_trom = split_dots[4].strip() + total_trom = split_dots[5].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_trom, decoder_trom, com_trom, rend_trom, total_trom] + + elif profile.upper() == "WMOPS": + encoder_complexity = split_dots[1].strip() + decoder_complexity = split_dots[2].strip() + total_complexity = split_dots[3].strip() + return [input_mode, bitrate, bandwidth, codec_mode, output_mode, encoder_complexity, decoder_complexity, total_complexity] + + else: + return [] + +def sanity_check_configurations(input_mode, bitrate, bandwidth, codec_mode, output_mode, profile_row_values): + if input_mode != profile_row_values[0]: + print("Input mode mismatch: " + input_mode + " != " + profile_row_values[0]) + return -1 + if bitrate != profile_row_values[1]: + print("Bitrate mismatch: " + bitrate + " != " + profile_row_values[1]) + return -1 + if bandwidth != profile_row_values[2]: + print("Bandwidth mismatch: " + bandwidth + " != " + profile_row_values[2]) + return -1 + if codec_mode != profile_row_values[3]: + print("Codec mode mismatch: " + codec_mode + " != " + profile_row_values[3]) + return -1 + if output_mode != profile_row_values[4]: + print("Output mode mismatch: " + output_mode + " != " + profile_row_values[4]) + return -1 + + return 0 + + +if __name__ == "__main__": + + # Parse arguments + parser = argparse.ArgumentParser(description='Argument parser') + parser.add_argument('-input_tables_base',type=str,help='Paths to base input tables csv files, separated by ;') + parser.add_argument('-output_table',type=str,help='Path to output table csv file') + parser.add_argument('-combined_max_output_table',type=str,help='Path to output table which contains the max wmops entry for each input format csv file') + parser.add_argument('-input_limiters',type=str,help='Limit the output table based on input formats, separated by ;') + parser.add_argument('-bitrate_limiters',type=str,help='Limit the output table based on bitrates, separated by ;') + parser.add_argument('-codec_mode_limiters',type=str,help='Limit the output table based on codec modes, separated by ;') + parser.add_argument('-bandwidth_limiters',type=str,help='Limit the output table based on bandwidths, separated by ;') + parser.add_argument('-output_limiters',type=str,help='Limit the output table based on output formats, separated by ;') + parser.add_argument('-profiler_limiters',type=str,help='Limit the included profiler analysis (e.g. WMOPS), separated by ;') + args = parser.parse_args() + input_tables_base = args.input_tables_base + output_table = args.output_table + combined_max_output_table = args.combined_max_output_table + input_limiters = args.input_limiters + bitrate_limiters = args.bitrate_limiters + codec_mode_limiters = args.codec_mode_limiters + bandwidth_limiters = args.bandwidth_limiters + output_limiters = args.output_limiters + profiler_limiters = args.profiler_limiters + single_input_format_output_table_base = None + + # Complexity levels + clevel_base = 128.86 + clevel1 = 3 * clevel_base + clevel2 = 6 * clevel_base + clevel3 = 10 * clevel_base + + # Limit the output table values + limiters = { + "input": [], + "bitrate": [], + "codec_mode": [], + "bandwidth": [], + "output": [], + } + input_modes = [ + "mono" + ,"stereodmxevs" + ,"stereo" + ,"masa 1tc" + ,"masa 2tc" + ,"ism1" + ,"ism2" + ,"ism3" + ,"ism4" + ,"ism+1" + ,"ism+2" + ,"ism+3" + ,"ism+4" + ,"omasa ism1 1tc" + ,"omasa ism1 2tc" + ,"omasa ism2 1tc" + ,"omasa ism2 2tc" + ,"omasa ism3 1tc" + ,"omasa ism3 2tc" + ,"omasa ism4 1tc" + ,"omasa ism4 2tc" + ,"mc 5_1" + ,"mc 5_1_2" + ,"mc 5_1_4" + ,"mc 7_1" + ,"mc 7_1_4" + ,"foa" + ,"hoa2" + ,"hoa3" + ,"planar foa" + ,"planar hoa2" + ,"planar hoa3" + ,"osba ism1 foa" + ,"osba ism1 hoa2" + ,"osba ism1 hoa3" + ,"osba ism2 foa" + ,"osba ism2 hoa2" + ,"osba ism2 hoa3" + ,"osba ism3 foa" + ,"osba ism3 hoa2" + ,"osba ism3 hoa3" + ,"osba ism4 foa" + ,"osba ism4 hoa2" + ,"osba ism4 hoa3"] + if input_limiters is not None: + input_modes = [] + input_limiters_list = input_limiters.split(";") + for in_limiter in input_limiters_list: + limiters["input"].append(in_limiter.lower()) + input_modes.append(in_limiter.lower()) + + ivas_bitrates = ['13.2','16.4','24.4','32','48','64','80','96','128','160','192','256','384','512'] + if bitrate_limiters is not None: + ivas_bitrates = [] + bitrate_limiters_list = bitrate_limiters.split(";") + for br_limiter in bitrate_limiters_list: + limiters["bitrate"].append(br_limiter.lower()) + ivas_bitrates.append(br_limiter.lower()) + + if codec_mode_limiters is not None: + codec_mode_limiters_list = codec_mode_limiters.split(";") + for cm_limiter in codec_mode_limiters_list: + limiters["codec_mode"].append(cm_limiter.lower()) + + if bandwidth_limiters is not None: + bandwidth_limiters_list = bandwidth_limiters.split(";") + for bw_limiter in bandwidth_limiters_list: + limiters["bandwidth"].append(bw_limiter.lower()) + + output_modes = ["mono","stereo","binaural","binaural_room_ir","binaural_room_reverb","foa","hoa2","hoa3","5_1","5_1_2","5_1_4","7_1","7_1_4","ext"] + if output_limiters is not None: + output_modes = [] + output_limiters_list = output_limiters.split(";") + for out_limiter in output_limiters_list: + limiters["output"].append(out_limiter.lower()) + output_modes.append(out_limiter.lower()) + + # Read table file base paths from arguments or use default ones + if input_tables_base is None: + path_to_files_str = "./" + file_path = os.path.abspath(path_to_files_str) + input_tables_base_list = [ + os.path.join(file_path, "ltv_complexity_mono_no_fec_"), + os.path.join(file_path, "ltv_complexity_FOA_no_fec_"), + os.path.join(file_path, "ltv_complexity_HOA2_no_fec_"), + os.path.join(file_path, "ltv_complexity_HOA3_no_fec_"), + os.path.join(file_path, "ltv_complexity_PlanarFOA_no_fec_"), + os.path.join(file_path, "ltv_complexity_PlanarHOA2_no_fec_"), + os.path.join(file_path, "ltv_complexity_PlanarHOA3_no_fec_"), + os.path.join(file_path, "ltv_complexity_MASA_no_fec_"), + os.path.join(file_path, "ltv_complexity_MC_no_fec_"), + os.path.join(file_path, "ltv_complexity_stereo_no_fec_"), + os.path.join(file_path, "ltv_complexity_stereoDmx_no_fec_"), + os.path.join(file_path, "ltv_complexity_OMASA_no_fec_"), + os.path.join(file_path, "ltv_complexity_OSBA_ISM1_no_fec_"), + os.path.join(file_path, "ltv_complexity_OSBA_ISM2_no_fec_"), + os.path.join(file_path, "ltv_complexity_OSBA_ISM3_no_fec_"), + os.path.join(file_path, "ltv_complexity_OSBA_ISM4_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM1_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM2_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM3_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM4_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM_plus1_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM_plus2_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM_plus3_no_fec_"), + os.path.join(file_path, "ltv_complexity_ISM_plus4_no_fec_")] + else: + input_tables_base_list = input_tables_base.split(";") + + # Create input table paths from the base path and profiler limiters + profile_table_lists = {} + all_profiles_included = False + if profiler_limiters is None: + included_profiles = ["HEAP_INTRA", "HEAP", "PROM", "RAM", "STACK", "TROM", "WMOPS"] + all_profiles_included = True + else: + included_profiles = profiler_limiters.split(";") + for profile in included_profiles: + profile_table_lists[profile] = [] + for input_file in input_tables_base_list: + profile_table_lists[profile].append(input_file + profile + ".csv") + + # Output table paths + output_profile_suffix = "" + if all_profiles_included: + output_profile_suffix = "_ALL" + else: + for profile in included_profiles: + output_profile_suffix += "_" + profile + if output_table is None: + out_dir = "complexity_tables" + if not os.path.exists(out_dir): + os.makedirs(out_dir) + output_table = os.path.join(out_dir, "combined_table" + output_profile_suffix +".csv") + temp_output_path_parent = os.path.abspath(os.path.join(os.path.abspath(output_table), os.pardir)) + single_input_format_output_table_base = os.path.join(temp_output_path_parent, "combined_table_") + heatmap_table_base = os.path.join(temp_output_path_parent, "heatmap_table_") + if combined_max_output_table is None: + combined_max_output_table = os.path.join(temp_output_path_parent, "max_input" + output_profile_suffix +".csv") + + # JSON output + json_output = output_table.replace(".csv", ".json") + + # Header fields in the output table + fields = ['Input', 'Bitrate', 'Codec mode', 'Bandwidth', 'Output'] + for profile in included_profiles: + if "HEAP_INTRA" in profile.upper(): + fields.append('ENC HEAP INTRA') + fields.append('DEC HEAP INTRA') + fields.append('Total HEAP INTRA') + elif "HEAP" in profile.upper(): + fields.append('ENC HEAP') + fields.append('DEC HEAP') + fields.append('Total HEAP') + elif "PROM" in profile.upper(): + fields.append('ENC PROM') + fields.append('DEC PROM') + fields.append('COM PROM') + fields.append('REND PROM') + fields.append('Total PROM') + elif "RAM" in profile.upper(): + fields.append('ENC RAM') + fields.append('DEC RAM') + fields.append('Total RAM') + elif "STACK" in profile.upper(): + fields.append('ENC STACK') + fields.append('DEC STACK') + fields.append('MAX STACK') + elif "TROM" in profile.upper(): + fields.append('ENC TROM') + fields.append('DEC TROM') + fields.append('COM TROM') + fields.append('REND TROM') + fields.append('Total TROM') + elif "WMOPS" in profile.upper(): + fields.append('ENC WMOPS') + fields.append('DEC WMOPS') + fields.append('Total WMOPS') + + # Dict for input format specific data: 0: max WMOPS, 1: data row for max WMOPS, 2: all data rows + input_formats_maxWmops_maxRow_dataRows = { + "FOA" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "HOA2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "HOA3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM+1" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM+2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM+3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM+4" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM1" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "ISM4" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MASA 1TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MASA 2TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MC 5_1" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MC 5_1_2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MC 5_1_4" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MC 7_1" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MC 7_1_4" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "MONO" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM1 1TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM1 2TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM2 1TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM2 2TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM3 1TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM3 2TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM4 1TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OMASA ISM4 2TC" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM1 FOA" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM1 HOA2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM1 HOA3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM2 FOA" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM2 HOA2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM2 HOA3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM3 FOA" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM3 HOA2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM3 HOA3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM4 FOA" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM4 HOA2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "OSBA ISM4 HOA3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "PLANAR FOA" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "PLANAR HOA2" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "PLANAR HOA3" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "STEREO" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + "STEREODMXEVS" : {"MaxWMOPS" : 0, "MaxDataRow" : {}, "DataRows" : []}, + } + + # Profile specific dicts (filled during run) + profile_table_files = {} + profile_csv_reader = {} + profile_row = {} + profile_row_values = {} + + # Excel stuff + output_table_xlsx = output_table.replace(".csv", ".xlsx") + combined_max_output_table_xlsx = combined_max_output_table.replace(".csv", ".xlsx") + wb_output_table = openpyxl.Workbook() + ws_output_table = wb_output_table.active + ws_output_table.append(fields) + wb_combined_max_output_table = openpyxl.Workbook() + ws_combined_max_output_table = wb_combined_max_output_table.active + ws_combined_max_output_table.append(fields) + os.makedirs(os.path.dirname(output_table), exist_ok=True) + whiteFill = openpyxl.styles.PatternFill(start_color='ffffff', end_color='ffffff', fill_type='solid') + blueFill = openpyxl.styles.PatternFill(start_color='00ffff', end_color='00ffff', fill_type='solid') + greenFill = openpyxl.styles.PatternFill(start_color='03fc73', end_color='03fc73', fill_type='solid') + redFill = openpyxl.styles.PatternFill(start_color='FFFF0000', end_color='FFFF0000', fill_type='solid') + + # Heatmap + fields_heatmap = ['Input','13.2','16.4','24.4','32','48','64','80','96','128','160','192','256','384','512'] + input_formats_heatmap = { + "MONO" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "FOA" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "HOA2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "HOA3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM+1" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM+2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM+3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM+4" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM1" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "ISM4" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MASA 1TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MASA 2TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MC 5_1" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MC 5_1_2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MC 5_1_4" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MC 7_1" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "MC 7_1_4" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM1 1TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM1 2TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM2 1TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM2 2TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM3 1TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM3 2TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM4 1TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OMASA ISM4 2TC" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM1 FOA" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM1 HOA2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM1 HOA3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM2 FOA" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM2 HOA2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM2 HOA3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM3 FOA" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM3 HOA2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM3 HOA3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM4 FOA" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM4 HOA2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "OSBA ISM4 HOA3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "PLANAR FOA" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "PLANAR HOA2" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "PLANAR HOA3" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "STEREO" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + "STEREODMXEVS" : {"13.2" : [0, whiteFill], "16.4" : [0, whiteFill], "24.4" : [0, whiteFill], "32" : [0, whiteFill], "48" : [0, whiteFill], "64" : [0, whiteFill], "80" : [0, whiteFill], "96" : [0, whiteFill], "128" : [0, whiteFill], "160" : [0, whiteFill], "192" : [0, whiteFill], "256" : [0, whiteFill], "384" : [0, whiteFill], "512" : [0, whiteFill]}, + } + heatmap_outputs = { + "mono" : copy.deepcopy(input_formats_heatmap), + "stereo" : copy.deepcopy(input_formats_heatmap), + "binaural" : copy.deepcopy(input_formats_heatmap), + "binaural_room_ir" : copy.deepcopy(input_formats_heatmap), + "binaural_room_reverb" : copy.deepcopy(input_formats_heatmap), + "foa" : copy.deepcopy(input_formats_heatmap), + "hoa2" : copy.deepcopy(input_formats_heatmap), + "hoa3" : copy.deepcopy(input_formats_heatmap), + "5_1" : copy.deepcopy(input_formats_heatmap), + "5_1_2" : copy.deepcopy(input_formats_heatmap), + "5_1_4" : copy.deepcopy(input_formats_heatmap), + "7_1" : copy.deepcopy(input_formats_heatmap), + "7_1_4" : copy.deepcopy(input_formats_heatmap), + "ext" : copy.deepcopy(input_formats_heatmap), + } + + with open(output_table, 'w') as output_file: + writer = csv.writer(output_file, delimiter=";") + writer.writerow(fields) + num_tables = len(profile_table_lists[next(iter(profile_table_lists))]) + for file_num in range(0, num_tables): + total_complexity = "0" + # Open files and create csv readers + for profile in included_profiles: + profile_table_files[profile] = open(profile_table_lists[profile][file_num], 'r') + profile_csv_reader[profile] = csv.reader(profile_table_files[profile]) + + # Loop over rows + row_count = sum(1 for row in profile_csv_reader[next(iter(profile_csv_reader))]) + profile_table_files[next(iter(profile_table_files))].seek(0) + for i in range(0, row_count): + # Get rows + for profile in included_profiles: + profile_row[profile] = next(profile_csv_reader[profile])[0] + if "kbps" in profile_row[next(iter(profile_row))]: + # Parse rows + for profile in included_profiles: + profile_row_values[profile] = parse_configuration(profile_row[profile], profile) + # Codec configuration from first profile and sanity check + input_mode = profile_row_values[next(iter(profile_row_values))][0] + bitrate = profile_row_values[next(iter(profile_row_values))][1] + bandwidth = profile_row_values[next(iter(profile_row_values))][2] + codec_mode = profile_row_values[next(iter(profile_row_values))][3] + output_mode = profile_row_values[next(iter(profile_row_values))][4] + for profile in included_profiles: + if sanity_check_configurations(input_mode, bitrate, bandwidth, codec_mode, output_mode, profile_row_values[profile]) < 0: + continue + # Check limiters + if limiters["input"] != [] and input_mode.lower() not in limiters["input"]: + continue + + if limiters["bitrate"] != [] and bitrate.lower() not in limiters["bitrate"]: + continue + + if limiters["codec_mode"] != []: + if "non-dtx" in limiters["codec_mode"]: + if "dtx" in codec_mode.lower(): + continue + else: + if len(limiters["codec_mode"]) > 1: + mode_included = False + for mode in limiters["codec_mode"]: + if mode.lower() in codec_mode.lower(): + mode_included = True + if not mode_included: + continue + else: + mode_included = False + for mode in limiters["codec_mode"]: + if mode.lower() in codec_mode.lower(): + mode_included = True + if not mode_included: + continue + + if limiters["bandwidth"] != [] and bandwidth.lower() not in limiters["bandwidth"]: + continue + + if limiters["output"] != [] and output_mode.lower() not in limiters["output"]: + continue + + # Form data row + data_row = [input_mode, bitrate, codec_mode, bandwidth, output_mode] + for profile in included_profiles: + for i in range (5, len(profile_row_values[profile])): + data_row.append(float(profile_row_values[profile][i])) + if "WMOPS" in profile.upper(): + total_complexity = profile_row_values[profile][7] + writer.writerow(data_row) + ws_output_table.append(data_row) + # Dict data + dict_data = {} + for fn in range(0, len(fields)): + dict_data[fields[fn]] = data_row[fn] + input_formats_maxWmops_maxRow_dataRows[input_mode.upper()]["DataRows"].append(dict_data) + # Save max complexity data row + if float(total_complexity) > input_formats_maxWmops_maxRow_dataRows[input_mode.upper()]["MaxWMOPS"]: + input_formats_maxWmops_maxRow_dataRows[input_mode.upper()]["MaxWMOPS"] = float(total_complexity) + input_formats_maxWmops_maxRow_dataRows[input_mode.upper()]["MaxDataRow"] = dict_data + # Heatmap + if codec_mode == "" and bitrate in ivas_bitrates: + if float(total_complexity) > heatmap_outputs[output_mode.lower()][input_mode.upper()][bitrate][0]: + heatmap_outputs[output_mode.lower()][input_mode.upper()][bitrate][0] = float(total_complexity) + if float(total_complexity) > clevel2: + heatmap_outputs[output_mode.lower()][input_mode.upper()][bitrate][1] = redFill + elif float(total_complexity) > clevel1: + heatmap_outputs[output_mode.lower()][input_mode.upper()][bitrate][1] = greenFill + else: + heatmap_outputs[output_mode.lower()][input_mode.upper()][bitrate][1] = blueFill + + # Close files + for profile in included_profiles: + profile_table_files[profile].close() + + # Write tables for individual input formats + if single_input_format_output_table_base != None: + for key in input_formats_maxWmops_maxRow_dataRows: + sinle_input_format_output = single_input_format_output_table_base + key.replace(" ", "_") + output_profile_suffix + ".csv" + sinle_input_format_output_xlsx = sinle_input_format_output.replace(".csv", ".xlsx") + wb_single_input_format_output_table = openpyxl.Workbook() + ws_single_input_format_output_table = wb_single_input_format_output_table.active + ws_single_input_format_output_table.append(fields) + with open(sinle_input_format_output, 'w') as single_input_format_output_file: + single_writer = csv.writer(single_input_format_output_file, delimiter=";") + single_writer.writerow(fields) + for row in input_formats_maxWmops_maxRow_dataRows[key]["DataRows"]: + data_row = [] + for data_key in row: + data_row.append(row[data_key]) + single_writer.writerow(data_row) + ws_single_input_format_output_table.append(data_row) + wb_single_input_format_output_table.save(sinle_input_format_output_xlsx) + # Dump to json + with open(json_output, "w") as json_file: + json.dump(input_formats_maxWmops_maxRow_dataRows, json_file) + + # Write the max wmops rows + with open(combined_max_output_table, 'w') as combine_max_output_file: + max_writer = csv.writer(combine_max_output_file, delimiter=";") + max_writer.writerow(fields) + for key in input_formats_maxWmops_maxRow_dataRows: + max_data_row = [] + for data_key in input_formats_maxWmops_maxRow_dataRows[key]["MaxDataRow"]: + max_data_row.append(input_formats_maxWmops_maxRow_dataRows[key]["MaxDataRow"][data_key]) + max_writer.writerow(max_data_row) + ws_combined_max_output_table.append(max_data_row) + + # Heatmap + if heatmap_table_base != None: + for output_mode in output_modes: + heatmap_output_table = heatmap_table_base + output_mode + ".xlsx" + wb_heatmap_table = openpyxl.Workbook() + ws_heatmap_table = wb_heatmap_table.active + ws_heatmap_table.append(fields_heatmap) + row = 1 + for input_mode in input_modes: + row += 1 + col = 1 + ws_heatmap_table.cell(row, col).value = input_mode + col +=1 + for bitrate in ivas_bitrates: + ws_heatmap_table.cell(row, col).value = heatmap_outputs[output_mode][input_mode.upper()][bitrate][0] + ws_heatmap_table.cell(row, col).fill = heatmap_outputs[output_mode][input_mode.upper()][bitrate][1] + col += 1 + wb_heatmap_table.save(heatmap_output_table) + + # Save Excel file + wb_output_table.save(output_table_xlsx) + wb_combined_max_output_table.save(combined_max_output_table_xlsx) + + diff --git a/scripts/parse_mld_xml.py b/scripts/parse_mld_xml.py index 84acf4fbba7df736869137058ba935f4dd8e3fba..7370cfe7ff3b39e2bb2319034b06880c77984070 100644 --- a/scripts/parse_mld_xml.py +++ b/scripts/parse_mld_xml.py @@ -28,13 +28,14 @@ if __name__ == "__main__": tree = ElementTree.parse(xml_report) testsuite = tree.find(".//testsuite") - print( - f"Found testsuite with {testsuite.get('tests')} tests and {testsuite.get('failures')} failures." - ) + testcases = tree.findall(".//testcase") results_unsorted = {} + passes = 0 + failures = 0 + errors = 0 for testcase in testcases: if testcase.find(".//skipped") is None: @@ -51,14 +52,29 @@ if __name__ == "__main__": p.get("name"): p.get("value") for p in testcase.findall(".//property") } + + if testcase.find('failure') is not None: + testresult = 'FAIL' + failures = failures + 1 + elif testcase.find('error') is not None: + testresult = 'ERROR' + errors = errors + 1 + else: + testresult = 'PASS' + passes = passes + 1 + properties_values = [str(properties_found.get(p)) for p in PROPERTIES] - outline = ";".join([fulltestname] + properties_values) + "\n" + outline = ";".join([fulltestname,testresult] + properties_values) + "\n" results_unsorted[fulltestname] = outline results_sorted = dict(sorted(results_unsorted.items())) with open(csv_file, "w") as outfile: - headerline = ";".join(["testcase"] + PROPERTIES) + "\n" + headerline = ";".join(["testcase","Result"] + PROPERTIES) + "\n" outfile.write(headerline) for test in results_sorted: outfile.write(results_sorted[test]) + + print( + f"Parsed testsuite with {passes+failures+errors} tests: {passes} passes, {failures} failures and {errors} errors." + ) diff --git a/scripts/patch_code_headers.sh b/scripts/patch_code_headers.sh index f1a2cfd9e396693c24d2ba277c64aba11e9d98dc..44bbc9751374cc123604597af2de48ee343e8879 100755 --- a/scripts/patch_code_headers.sh +++ b/scripts/patch_code_headers.sh @@ -56,14 +56,23 @@ if [ $help -ne 0 ]; then fi +date="May 14, 2024" +version="IVAS-FL-2.0" + + # # C-Code # c_header_new=\ -'/*==================================================================================== - 3GPP TS26.258 Aug 24, 2023. IVAS Codec Version IVAS-FL-1.0 - ====================================================================================*/' +"/*==================================================================================== + 3GPP TS26.258 $date. IVAS Codec Version $version + ====================================================================================*/" + +matlab_header_new=\ +"% ==================================================================================== +% 3GPP TS26.258 $date. IVAS Codec Version $version +% ====================================================================================" #### @@ -139,8 +148,80 @@ rm -f $tmpfile # Patch Printout # -sed -i.bak -e "s/IVAS\ Codec\ Baseline/IVAS\ Codec\ Version\ IVAS-FL-1\.0/g" $WORKDIR/lib_com/disclaimer.c +sed -i.bak -e "s/IVAS\ Codec\ Baseline/IVAS\ Codec\ Version\ $version/g" $WORKDIR/lib_com/disclaimer.c + +# +# Patch Matlab Scripts +# + +find $WORKDIR -name "*.m" -exec sed -i.bak -e "/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/,+31d" \{\} \; + +# add new header +tmpfile=`mktemp` +rm -f $tmpfile +touch $tmpfile +echo "$matlab_header_new" >> $tmpfile +find $WORKDIR -name "*.m" -exec sed -i.bak -e "1 e cat $tmpfile" \{\} \; +rm -f $tmpfile + + +# +# Patch Output of Matlab Scripts +# + +sed -i.bak -e "/\/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/,+30d" $WORKDIR/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_rom_tables.m +sed -i.bak -e "/copyright_str\ =\ string[(]join[(]/a \ \ \ \ \'/*====================================================================================\'\n\ \ \ \ \'\ \ \ \ \ 3GPP\ TS26\.258\ $date\.\ IVAS\ Codec\ Version\ $version\'\n\ \ \ \ \'\ \ ====================================================================================*/\'" $WORKDIR/scripts/binauralRenderer_interface/matlab_hrir_generation_scripts/generate_rom_tables.m + +sed -i.bak -e "/\/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/,+30d" $WORKDIR/scripts/td_object_renderer/modeling_tool/Gen_Hrf_IVAS_Binary.m +sed -i.bak -e "/copyright_str\ =\ string[(]join[(]/a \ \ \ \ \'/*====================================================================================\'\n\ \ \ \ \'\ \ \ \ \ 3GPP\ TS26\.258\ $date\.\ IVAS\ Codec\ Version\ $version\'\n\ \ \ \ \'\ \ ====================================================================================*/\'" $WORKDIR/scripts/td_object_renderer/modeling_tool/Gen_Hrf_IVAS_Binary.m + + +# +# Patch header template for files generated by scripts +# + +truncate -s 0 $WORKDIR/scripts/binauralRenderer_interface/ivas_license_header.template +echo "$c_header_new" >> $WORKDIR/scripts/binauralRenderer_interface/ivas_license_header.template +sed -i.bak -e "1,/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\//d" $WORKDIR/scripts/binauralRenderer_interface/ivas_rom_binaural_crend_head.template +# add new header +tmpfile=`mktemp` +rm -f $tmpfile +touch $tmpfile +echo "$c_header_new" >> $tmpfile +sed -i.bak -e "1 e cat $tmpfile" $WORKDIR/scripts/binauralRenderer_interface/ivas_rom_binaural_crend_head.template +rm -f $tmpfile + + +# +# Various Readmes in scripts directory +# + +# C-style header +sed -i.bak -e "1,/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\//d" $WORKDIR/scripts/binauralRenderer_interface/Table_Format_Converter/tables_format_converter_readme.txt +sed -i.bak -e "1,/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\//d" $WORKDIR/scripts/binauralRenderer_interface/mixer_conv_sofa_to_rom_table_converter_readme.txt +# add new header +tmpfile=`mktemp` +rm -f $tmpfile +touch $tmpfile +echo "$c_header_new" >> $tmpfile +sed -i.bak -e "1 e cat $tmpfile" $WORKDIR/scripts/binauralRenderer_interface/Table_Format_Converter/tables_format_converter_readme.txt +sed -i.bak -e "1 e cat $tmpfile" $WORKDIR/scripts/binauralRenderer_interface/mixer_conv_sofa_to_rom_table_converter_readme.txt +rm -f $tmpfile + +# *.md-style header +sed -i.bak -e "1,/-->/d" $WORKDIR/scripts/binauralRenderer_interface/README.md +sed -i.bak -e "1,/-->/d" $WORKDIR/scripts/td_object_renderer/modeling_tool/README.md +# add new header +tmpfile=`mktemp` +rm -f $tmpfile +touch $tmpfile +echo '' >> $tmpfile +sed -i.bak -e "1 e cat $tmpfile" $WORKDIR/scripts/binauralRenderer_interface/README.md +sed -i.bak -e "1 e cat $tmpfile" $WORKDIR/scripts/td_object_renderer/modeling_tool/README.md +rm -f $tmpfile # # Remove License file diff --git a/scripts/prepare_delivery.sh b/scripts/prepare_delivery.sh index 0bd36278f1434919f8ded0ee7e84daa8e843eaa9..ac93a91043c90ec4b741136373aba7bfcf6486bb 100755 --- a/scripts/prepare_delivery.sh +++ b/scripts/prepare_delivery.sh @@ -35,7 +35,6 @@ DATE=`eval date +%Y_%m_%d` OUTDIR=c-code TMPCLEANDIR=clean-c-code ROOT=$(dirname $0)/.. -STRIP_SPLITREND=0 PREPARE_ZIP=1 # check, whether coan exists @@ -56,9 +55,6 @@ while getopts "$ALL_OPTS" OPTION; do case "${OPTION}" in -) case "${OPTARG}" in - strip_sr) - STRIP_SPLITREND=1 - ;; no_zip) PREPARE_ZIP=0 ;; @@ -69,7 +65,7 @@ while getopts "$ALL_OPTS" OPTION; do ;; esac;; h) - echo "usage: $0 [--strip_sr] [--no_zip]" >&2 + echo "usage: $0 [--no_zip]" >&2 exit -1 ;; *) @@ -98,6 +94,7 @@ cp -R ${ROOT}/lib_dec $OUTDIR cp -R ${ROOT}/lib_enc $OUTDIR cp -R ${ROOT}/lib_util $OUTDIR cp -R ${ROOT}/lib_rend $OUTDIR +cp -R ${ROOT}/lib_isar $OUTDIR cp -R ${ROOT}/lib_lc3plus $OUTDIR cp -R ${ROOT}/apps $OUTDIR mkdir $OUTDIR/lib_debug @@ -115,75 +112,23 @@ rm -f ${OUTDIR}/Workspace_msvc/lib_debug.vcxproj.bak rm -f ${OUTDIR}/lib_util/tsm_scale_file_reader.[ch] sed -i.bak -e "/lib_util\\\tsm_scale_file_reader.[ch]/d" ${OUTDIR}/Workspace_msvc/lib_util.vcxproj +# scripts for custom HRIR/BRIR ROM table/file generation +mkdir $OUTDIR/scripts +cp -R ${ROOT}/scripts/binauralRenderer_interface $OUTDIR/scripts +cp -R ${ROOT}/scripts/td_object_renderer $OUTDIR/scripts + # readme cp ${ROOT}/readme.txt ${OUTDIR} recode lat1..ibmpc ${OUTDIR}/readme.txt # unix2dos ... -# readme_split_rendering -cp ${ROOT}/readme_split_rendering.txt ${OUTDIR} -recode lat1..ibmpc ${OUTDIR}/readme_split_rendering.txt # unix2dos ... - # LICENSE.md cp ${ROOT}/LICENSE.md ${OUTDIR} recode lat1..ibmpc ${OUTDIR}/LICENSE.md # unix2dos ... -# include .clang_format, since this is a VS dependency -cp ${ROOT}/.clang-format ${OUTDIR} - # enable split rendering againg by default -# in case we strip it later, it will be explicitly disabled again belo +# in case we strip it later, it will be explicitly disabled again below sed -i.bak -e "s/\/\*\ *\(#define\ *SPLIT_REND_WITH_HEAD_ROT\ *\)\*\//\1/g" ${OUTDIR}/lib_com/options.h - -########################## -# # -# Strip Split Rendering # -# # -########################## - -if [ $STRIP_SPLITREND -ne 0 ]; then - - echo "Stripping Split Rendering" - - ${ROOT}/scripts/strip_split_rendering.sh ${OUTDIR} - - # strip macros - declare -a sr_macros=( - "SPLIT_REND_WITH_HEAD_ROT" - ) - - if coan_exists; then - - for macro in ${sr_macros[@]}; do - coan source --replace --no-transients -K -U${macro} $OUTDIR/lib_{com,dec,enc,util,rend}/*.[hc] - coan source --replace --no-transients -K -U${macro} $OUTDIR/apps/*.[hc] - sed -i.bak "/#define\ *$macro/d" $OUTDIR/lib_com/options.h - done - - else - - echo "Coan required in path; Aborting. Available at https://coan2.sourceforge.net/" - exit -1 - - fi - - # patch Makefile - patch ${OUTDIR}/Makefile < ${ROOT}/scripts/makefile_noSR.patch - - # delete readme_split_rendering - rm ${OUTDIR}/readme_split_rendering.txt - - # clean-up *.bak-files - find $OUTDIR -name "*.bak" -exec rm \{\} \; - -else - - # patch Makefile so that split rendering sources are built by default - patch ${OUTDIR}/Makefile < ${ROOT}/scripts/makefile_SR.patch - -fi - - ########################## # # # Stripping # @@ -206,7 +151,7 @@ if coan_exists; then ${ROOT}/scripts/parse_options_h.sh -c $tmpfile >> $COAN_LIST # apply coan - coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend}/*.[hc] + coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend,isar}/*.[hc] coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/apps/*.[hc] # remove rejected switches from options.h @@ -292,6 +237,7 @@ if coan_exists; then echo "-UDEBUG_AGC_ENCODER_CMD_OPTION" >> $COAN_LIST echo "-UDEBUG_JBM_CMD_OPTION" >> $COAN_LIST echo "-UVARIABLE_SPEED_DECODING" >> $COAN_LIST + echo "-UDISABLE_LIMITER" >> $COAN_LIST echo "-UDBG_WAV_WRITER" >> $COAN_LIST echo "-USPLIT_REND_WITH_HEAD_ROT_DEBUG" >> $COAN_LIST echo "-USPLIT_POSE_CORRECTION_DEBUG" >> $COAN_LIST @@ -306,7 +252,7 @@ if coan_exists; then rm -f $tmpfile # apply coan - coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend}/*.[hc] + coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/lib_{com,dec,enc,util,rend,isar}/*.[hc] coan source --replace --no-transients -K --file $COAN_LIST $OUTDIR/apps/*.[hc] # remove rejected switches from options.h diff --git a/scripts/prepare_instrumentation.sh b/scripts/prepare_instrumentation.sh index 777bc88230bd60791b271c412b4c5c719bfda22c..08c595b35cdea9f9eae8a6e0ed58a6886d4e0469 100755 --- a/scripts/prepare_instrumentation.sh +++ b/scripts/prepare_instrumentation.sh @@ -39,13 +39,7 @@ function usage { exit } -if [ -z "$1" ] || [ "$1" == "sr_off" ]; then - INCLUDE_SPLIT=0 -elif [ "$1" == "sr_on" ]; then - INCLUDE_SPLIT=1 -else - usage -fi +INCLUDE_SPLIT=1 system=`uname -s` @@ -93,6 +87,35 @@ fi rm -f $ifdef_list touch $ifdef_list +# Add LC3plus feature defines to options.h so that they are stripped correctly +if [ $INCLUDE_SPLIT -eq 1 ]; then + # Generate list of active defines in LC3plus defines.h + lc3plus_defines=$( + gcc -E -dM $targetdir/lib_lc3plus/defines.h -I $targetdir/lib_com -I $targetdir/lib_debug | + sed '/^#define [[:alnum:]][[:alnum:]_]\+[[:space:]]*$/! d' | + sed '/#define DEFINES_H/ d' + ) + + # Filter defines that come from outside of the header lib_lc3plus/defines.h + lc3plus_defines_filtered="" + while IFS=' \n' read -r line; + do + line=`echo $line | tr -d '\n'` + if grep -wqF "$line" "$targetdir/lib_lc3plus/defines.h"; then + lc3plus_defines_filtered+=$line$'\n' + fi + done <<< $lc3plus_defines + + # Append LC3plus defines to options.h + echo " +/* LC3plus switches */ +#ifndef OPTIONS_H_LC3_DEFINES +#define OPTIONS_H_LC3_DEFINES +$lc3plus_defines_filtered +#endif /* OPTIONS_H_LC3_DEFINES */ +" >>$targetdir/lib_com/options.h +fi + # get switches from options.h and append it to $ifdef_list parse_options_opt="" if coan_exists; then @@ -113,8 +136,10 @@ if coan_exists; then sed -i "/-DWMOPS/d" $ifdef_list sed -i "/-UMEM_COUNT_DETAILS/d" $ifdef_list - coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/lib_{com,dec,enc,rend,util,debug}/!(wmc_auto*).[hc] + coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/lib_{com,dec,enc,isar,rend,util,debug}/!(wmc_auto*).[hc] coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/apps/*.[hc] + coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/lib_lc3plus/!(wmc_auto*).[hc] + coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/lib_lc3plus/fft/!(wmc_auto*).[hc] else ./strip_defines_cppp.sh $targetdir $ifdef_list fi @@ -128,6 +153,7 @@ find $targetdir -name "*.[ch]" -exec sed -i.bak -e "s/\(0x[0-9a-fA-F]*\)UL/\(\(u "tools/$system/wmc_tool" -m "$targetdir/apps/decoder.c" "$targetdir/lib_dec/*.c" "$targetdir/lib_rend/*.c" >> /dev/null if [ $INCLUDE_SPLIT -eq 1 ]; then "tools/$system/wmc_tool" -m "$targetdir/apps/renderer.c" "$targetdir/lib_rend/*.c" "$targetdir/lib_lc3plus/*.c" "$targetdir/lib_lc3plus/fft/*.c" >> /dev/null + "tools/$system/wmc_tool" -m "$targetdir/apps/isar_post_rend.c" "$targetdir/lib_isar/*.c" "$targetdir/lib_lc3plus/*.c" "$targetdir/lib_lc3plus/fft/*.c" >> /dev/null fi # automatically enable #define WMOPS in options.h diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index 8fabd5ca1c6a963b79fc1068cbf494874fd01849..d89c079d8989d87841c8d95ac2d425639b92d7ca 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -334,8 +334,8 @@ def compare( for i in range(nchannels): tmpfile_ref = Path(tmpdir).joinpath(f"ref_ch{i+1}.wav") tmpfile_test = Path(tmpdir).joinpath(f"test_ch{i+1}.wav") - r48 = resample(ref[:, i], fs, 48000) - t48 = resample(test[:, i], fs, 48000) + r48 = np.clip( resample(ref[:, i].astype(float), fs, 48000), -32768, 32767 ).astype(np.int16) # Convert to float for resample, then to int16 for wavfile.write + t48 = np.clip( resample(test[:, i].astype(float), fs, 48000), -32768, 32767 ).astype(np.int16) wavfile.write(str(tmpfile_ref), 48000, r48) wavfile.write(str(tmpfile_test), 48000, t48) out = subprocess.check_output([mld, tmpfile_ref, tmpfile_test]) diff --git a/scripts/reverb/generate_acoustic_environments_metadata.py b/scripts/reverb/generate_acoustic_environments_metadata.py index 58017d983b44d2f5bf40934e82215e8ab805dd7c..cba887724cf60d7a944340e875c121a060957d37 100644 --- a/scripts/reverb/generate_acoustic_environments_metadata.py +++ b/scripts/reverb/generate_acoustic_environments_metadata.py @@ -731,6 +731,17 @@ def get_angle_code(angle): assert 0 <= angle <= 360 return usquant(angle, 0, 20, 19) +def get_refdist_code(dist): + assert 0 <= dist + return usquant(dist, 0.1, 0.1, 64) + +def get_maxdist_code(dist): + assert 0 <= dist + return usquant(dist, 1, 1, 64) + +def get_rolloff_code(rollof): + assert 0 <= rollof + return usquant(rollof, 0, 0.1, 41) def get_outer_attenuation_code(att): assert 0 <= att <= 1 diff --git a/scripts/reverb/text_to_binary_payload.py b/scripts/reverb/text_to_binary_payload.py index 7eff404a7a8a9d16f37fc9d24ee34391ed81a4c2..4f958c75129d7d8c4d912b6b29cd51d59f7f5fa0 100644 --- a/scripts/reverb/text_to_binary_payload.py +++ b/scripts/reverb/text_to_binary_payload.py @@ -84,6 +84,7 @@ def parse_reverb_text_configuration_and_generate_binary_payload(file): "acousticEnvironment", "directivitySetting", "directivityPattern", + "distanceAttenuation", ] } for section_name in config.sections(): @@ -99,6 +100,7 @@ def parse_reverb_text_configuration_and_generate_binary_payload(file): assert section_name in [ "roomAcoustics", "directivitySetting", + "distanceAttenuation", ], f"unknown section name: {section_name}" sections[section_name] = config[section_name] @@ -229,10 +231,19 @@ def parse_reverb_text_configuration_and_generate_binary_payload(file): + get_angle_code(dir_values[1]) # Directivity outer angle + get_outer_attenuation_code(dir_values[2]) ) # Directivity outer attenuation + + # parse distance attenuation + hasDistanceAttenuation = len(sections["distanceAttenuation"]) > 0 + data += get_bool_code(hasDistanceAttenuation) + if hasDistanceAttenuation: + data += bitarray( + get_maxdist_code(eval_option(sections["distanceAttenuation"]["maxDist"])) # Distance attenuation Max Distance + + get_refdist_code(eval_option(sections["distanceAttenuation"]["refDist"])) # Distance attenuation Ref Distance + + get_rolloff_code(eval_option(sections["distanceAttenuation"]["rolloffFactor"])) # Distance attenuation Rolloff Factor + ) # generate binary file data.tofile(open(file.split(".")[0] + ".dat", "wb")) - if __name__ == "__main__": import argparse diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c index 83844f6a781a56dd2425aa2cd2d5f7ec3a75a356..725cf525c31af0b023e0ae44ad6b01ed94fa9af3 100644 --- a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c @@ -30,44 +30,46 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ +#include #include #include #include "options.h" -#include "ivas_lc3plus_enc.h" -#include "ivas_lc3plus_common.h" -#include "ivas_lc3plus_dec.h" +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_common.h" +#include "isar_lc3plus_dec.h" #include "ivas_error_utils.h" +#include "lc3.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT +#define MAX_SAMPLES_PER_CHANNEL 960 / 4 +#define DEFAULT_BPS 256000 -#define MAX_SAMPLES_PER_CHANNEL 960 - -static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) +static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config, uint32_t bps ) { ivas_error err; - uint32_t bps = 128000; int32_t encDelay = -1; int32_t decDelay = -1; - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) { return err; } - err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); + err = ISAR_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); if ( IVAS_ERR_OK != err ) { + ISAR_LC3PLUS_ENC_Close( &encHandle ); return err; } if ( encDelay == -1 || encDelay == 0 ) { + ISAR_LC3PLUS_ENC_Close( &encHandle ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); } /* encode one frame */ - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); float *pcm_in[2]; float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); @@ -77,37 +79,62 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) pcm_in[1] = pcm_in_ch2; int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); return err; - + } uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + int perChannelBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + int perLc3plusFrameDataBlockOctets = encHandle->num_ftds * perChannelBitrate / 8 / (1000*1000/config.lc3plus_frame_duration_us); + int targetOctets = bps / 8 / (1000*1000/config.isar_frame_duration_us); + printf("IVAS-FS=%i LC3plus-FS=%i ch=%i targetBps=%i targetOctets=%i\n", config.isar_frame_duration_us, config.lc3plus_frame_duration_us, config.channels, bps, targetOctets); + printf(" coreBps=%i corePerChBps=%i coreCodecOctets=%i nFtds=%i \n", perChannelBitrate * encHandle->num_encs, perChannelBitrate, perLc3plusFrameDataBlockOctets, encHandle->num_ftds); + int pfOctets = bitstreamSizePerIvasFrame - perLc3plusFrameDataBlockOctets; + int pfBps = pfOctets * 8 * (1000*1000 / config.isar_frame_duration_us); + printf(" payloadFormatBps=%i payloadFormatOctets=%i \n\n", pfBps, pfOctets); + if(pfBps <= 0) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + return err; + } + + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) + { + ISAR_LC3PLUS_ENC_Close( &encHandle ); + free( bitstream_out ); return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); + } + ISAR_LC3PLUS_ENC_Close( &encHandle ); /* decode one frame */ - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif &decHandle ); if ( IVAS_ERR_OK != err ) { + free( bitstream_out ); return err; } - err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); + err = ISAR_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); if ( IVAS_ERR_OK != err ) { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } if ( decDelay == -1 || decDelay == 0 ) { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); } @@ -121,25 +148,31 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) pcm_out[0] = pcm_out_ch1; pcm_out[1] = pcm_out_ch2; - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); if ( IVAS_ERR_OK != err ) { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { + ISAR_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return 0; @@ -149,53 +182,60 @@ static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) static int openCloseEncoder( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; uint32_t bps = 128000; - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) { return err; } - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); return 0; } static int tryOpenEncoderWithInvalidBitrate( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; /* lc3plus max bitrate is 320000 per channel */ uint32_t invalid_high_bps = 700000; uint32_t invalid_low_bps = 8; - - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); - /* setting an invalid bitrate should trigger an error - which is what we expect */ - if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) + uint32_t limitedBitrate; + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); + /* setting an invalid bitrate should result in a limited bitrate*/ + if ( IVAS_ERR_OK != err ) + { + return 1; + } + limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + if(limitedBitrate != 320000) { return 1; } - err = IVAS_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); + ISAR_LC3PLUS_ENC_Close(&encHandle); + err = ISAR_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); /* setting an invalid bitrate should trigger an error - which is what we expect */ if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) { return 1; } + ISAR_LC3PLUS_ENC_Close(&encHandle); return 0; } static int tryOpenEncoderWithInvalidFrameDuration( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ uint32_t bps = 320000; - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); /* setting an invalid fame duration should trigger an error - which is what we expect */ if ( IVAS_ERR_OK == err ) { @@ -207,12 +247,12 @@ static int tryOpenEncoderWithInvalidFrameDuration( void ) static int tryOpenEncoderWithInvalidSampleRate( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; config.samplerate = 1234; /*unsupported sample rate */ uint32_t bps = 320000; - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); /* setting an invalid sample rate should trigger an error - which is what we expect */ if ( IVAS_ERR_OK == err ) { @@ -223,7 +263,7 @@ static int tryOpenEncoderWithInvalidSampleRate( void ) static int tryCallEncoderApiWithInvalidParams( void ) { - IVAS_LC3PLUS_ENC_HANDLE invalidEncHandle = NULL; + ISAR_LC3PLUS_ENC_HANDLE invalidEncHandle = NULL; int32_t *invalidBsSize = NULL; int32_t bsSize; int32_t *invalidDelayInSamples = NULL; @@ -238,20 +278,20 @@ static int tryCallEncoderApiWithInvalidParams( void ) pcm_in[0] = pcm_in_ch1; uint8_t bitstream_out[1200]; - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) ) { return 1; } - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) ) { return 1; } - IVAS_LC3PLUS_ENC_Close( &invalidEncHandle ); - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) + ISAR_LC3PLUS_ENC_Close( &invalidEncHandle ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize ) ) { return 1; } - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out, bsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out, bsSize ) ) { return 1; } @@ -261,7 +301,7 @@ static int tryCallEncoderApiWithInvalidParams( void ) static int tryCallDecoderApiWithInvalidParams( void ) { - IVAS_LC3PLUS_DEC_HANDLE invalidDecHandle = NULL; + ISAR_LC3PLUS_DEC_HANDLE invalidDecHandle = NULL; int32_t *invalidDelayInSamples = NULL; int32_t delayInSamples; @@ -277,17 +317,17 @@ static int tryCallDecoderApiWithInvalidParams( void ) pcm_out[0] = pcm_out_ch1; uint8_t bitstream_in[1200]; - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) ) { return 1; } - IVAS_LC3PLUS_DEC_Close( &invalidDecHandle ); - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) ) + ISAR_LC3PLUS_DEC_Close( &invalidDecHandle ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) ) { return 1; } - if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) ) + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) ) { return 1; } @@ -297,10 +337,9 @@ static int tryCallDecoderApiWithInvalidParams( void ) static int openCloseDecoderWithCaching( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; - - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -310,17 +349,16 @@ static int openCloseDecoderWithCaching( void ) return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); return 0; } static int openCloseDecoderWithoutCaching( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; - - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -330,7 +368,7 @@ static int openCloseDecoderWithoutCaching( void ) return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); return 0; } @@ -338,11 +376,11 @@ static int openCloseDecoderWithoutCaching( void ) static int tryOpenDecoderWithInvalidFrameDuration( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -358,11 +396,11 @@ static int tryOpenDecoderWithInvalidFrameDuration( void ) static int tryOpenDecoderWithInvalidSampleRate( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; config.samplerate = 1234; /*unsupported sample rate*/ - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -378,15 +416,15 @@ static int tryOpenDecoderWithInvalidSampleRate( void ) static int encodeOneFrame( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; uint32_t bps = 128000; - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) return err; - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); float *pcm[1]; float pcm_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; @@ -394,17 +432,16 @@ static int encodeOneFrame( void ) pcm[0] = pcm_ch1; int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) return err; uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); free( bitstream_out ); return 0; } @@ -413,39 +450,38 @@ static int encodeOneFrame( void ) static int encodeAndDecodeOneMonoFrame( void ) { ivas_error err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; uint32_t bps = 128000; - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, bps, &encHandle ); if ( IVAS_ERR_OK != err ) { return err; } /* encode one frame */ - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.isar_frame_duration_us ); float *pcm_in[1]; float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); pcm_in[0] = pcm_in_ch1; int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + err = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) return err; uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); if ( IVAS_ERR_OK != err ) return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); /* decode one frame */ - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -461,19 +497,19 @@ static int encodeAndDecodeOneMonoFrame( void ) float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); pcm_out[0] = pcm_out_ch1; - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + err = ISAR_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); if ( IVAS_ERR_OK != err ) { return err; } - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + err = ISAR_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); if ( IVAS_ERR_OK != err ) { return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); free( bitstream_out ); return 0; @@ -481,151 +517,206 @@ static int encodeAndDecodeOneMonoFrame( void ) static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) { - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; - return encodeAndDecodeOneStereoFrame( config ); + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 ); } -#include "ivas_lc3plus_unit_test_selective_decoding.c" +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 98*1000 ); +} +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_126kbpsPerChannel( void ) +#else +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel( void ) +#endif +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 204800 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 205600 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 206400 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; + return encodeAndDecodeOneStereoFrame( config, config.channels * 207200 ); +} + +#include "ivas_lc3plus_unit_test_payload_format.c" int main( int argc, char *argv[] ) { + (void)argc; + (void)argv; int ret = 0; ret = openCloseEncoder(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenEncoderWithInvalidBitrate(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenEncoderWithInvalidFrameDuration(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenEncoderWithInvalidSampleRate(); if ( ret != 0 ) - return ret; + return 1; ret = tryCallEncoderApiWithInvalidParams(); if ( ret != 0 ) - return ret; + return 1; ret = openCloseDecoderWithCaching(); if ( ret != 0 ) - return ret; + return 1; ret = openCloseDecoderWithoutCaching(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenDecoderWithInvalidFrameDuration(); if ( ret != 0 ) - return ret; + return 1; ret = tryOpenDecoderWithInvalidSampleRate(); if ( ret != 0 ) - return ret; + return 1; ret = tryCallDecoderApiWithInvalidParams(); if ( ret != 0 ) - return ret; + return 1; ret = encodeOneFrame(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneMonoFrame(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz(); + if ( ret != 0 ) + return 1; ret = encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz(); if ( ret != 0 ) - return ret; + return 1; ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_all_subframes(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_2_subframes(); - if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_3_subframes(); + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_skip_first_subframe(); + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_cache(); + return 1; +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_126kbpsPerChannel(); +#else + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_124kbpsPerChannel(); +#endif if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_skip_first(); + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first(); + return 1; + /* start configs around the FDL threshold */ + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_dec_first(); + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_skip_first(); + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_get_active_dont_cache(); + return 1; + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel(); if ( ret != 0 ) - return ret; -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first_no_caching(); + return 1; + /* end configs around the FDL threshold */ + ret = run_all_payload_tests(); if ( ret != 0 ) - return ret; -#endif - return ret; -} -#else -int main( void ) -{ - return EXIT_SUCCESS; + return 1; + return 0; } -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c new file mode 100644 index 0000000000000000000000000000000000000000..88ee6783df3572b674e3017e9cdabf218bb4a065 --- /dev/null +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c @@ -0,0 +1,449 @@ +/****************************************************************************************************** + +(C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "ivas_error_utils.h" +#include "isar_lc3plus_common.h" +#include "options.h" + + +/* included by ivas_lc3plus_unit_test.c */ + +#define LC3PLUS_MAX_NUM_CODERS 16 +#define LC3PLUS_MAX_BS_SIZE LC3PLUS_MAX_NUM_CODERS *( 720 * LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES ) +#define SIZE_70 70 +#define SIZE_160 160 +#define SIZE_320 320 +#define SIZE_600 600 + +static int pack_and_unpack_payload_config_2ch_10ms_lc3plus_20ms_ivas( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_160; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_01 = &sender_ftds[1]; + ftd_R_01->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_01->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_R_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_01->frame_data = NULL; + ftd_R_01->frame_data_length = SIZE_600; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_02 = &sender_ftds[2]; + ftd_L_02->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_02->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_L_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_02->frame_data = NULL; + ftd_L_02->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_02 = &sender_ftds[3]; + ftd_R_02->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_R_02->fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + ftd_R_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_02->frame_data = NULL; + ftd_R_02->frame_data_length = SIZE_160; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_160]; + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + uint8_t frame_data_R_01[SIZE_600]; + memset( frame_data_R_01, 0x02, sizeof( frame_data_R_01 ) ); + uint8_t frame_data_L_02[SIZE_320]; + memset( frame_data_L_02, 0x03, sizeof( frame_data_L_02 ) ); + uint8_t frame_data_R_02[SIZE_160]; + memset( frame_data_R_02, 0x04, sizeof( frame_data_R_02 ) ); + memcpy( sender_ftds[0].frame_data, frame_data_L_01, sender_ftds[0].frame_data_length ); + memcpy( sender_ftds[1].frame_data, frame_data_R_01, sender_ftds[1].frame_data_length ); + memcpy( sender_ftds[2].frame_data, frame_data_L_02, sender_ftds[2].frame_data_length ); + memcpy( sender_ftds[3].frame_data, frame_data_R_02, sender_ftds[3].frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + + assert( payload_config.fdl_request == fdl_req ); + assert( payload_config.frame_duration_us == 10000 ); + assert( payload_config.high_resolution_enabled == 0 ); + assert( payload_config.sampling_rate_hz == 48000 ); + assert( payload_config.num_ftds == 4 ); + assert( payload_config.num_media_times == 2 ); + assert( payload_config.num_channels == 2 ); + for ( int32_t i = 0; i < payload_config.num_ftds; ++i ) + { + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].h == sender_ftds[i].h ); + assert( payload_config.ftds[i].fdi == sender_ftds[i].fdi ); + assert( payload_config.ftds[i].bwr == sender_ftds[i].bwr ); + assert( payload_config.ftds[i].fc == sender_ftds[i].fc ); + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].frame_data != sender_ftds[i].frame_data ); + assert( 0 == memcmp( payload_config.ftds[i].frame_data, sender_ftds[i].frame_data, sender_ftds[i].frame_data_length ) ); + } + + free( receiverBuffer ); + return 0; +} + +static int pack_and_unpack_payload_config_2ch_5ms_lc3plus_20ms_ivas( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_01 = &sender_ftds[1]; + ftd_R_01->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_01->frame_data = NULL; + ftd_R_01->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_02 = &sender_ftds[2]; + ftd_L_02->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_02->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_02->frame_data = NULL; + ftd_L_02->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_02 = &sender_ftds[3]; + ftd_R_02->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_02->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_02->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_02->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_02->frame_data = NULL; + ftd_R_02->frame_data_length = SIZE_160; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_03 = &sender_ftds[4]; + ftd_L_03->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_03->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_03->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_03->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_03->frame_data = NULL; + ftd_L_03->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_03 = &sender_ftds[5]; + ftd_R_03->fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + ftd_R_03->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_03->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_03->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_03->frame_data = NULL; + ftd_R_03->frame_data_length = SIZE_320; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_L_04 = &sender_ftds[6]; + ftd_L_04->fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + ftd_L_04->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_04->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_04->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_04->frame_data = NULL; + ftd_L_04->frame_data_length = SIZE_70; + sender_ftds_num++; + + LC3PLUS_RTP_FTD *ftd_R_04 = &sender_ftds[7]; + ftd_R_04->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_R_04->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_R_04->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_R_04->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_R_04->frame_data = NULL; + ftd_R_04->frame_data_length = SIZE_160; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_70]; + assert( ftd_L_01->frame_data_length == sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + uint8_t frame_data_R_01[SIZE_320]; + assert( ftd_R_01->frame_data_length == sizeof( frame_data_R_01 ) ); + memset( frame_data_R_01, 0x02, sizeof( frame_data_R_01 ) ); + uint8_t frame_data_L_02[SIZE_70]; + assert( ftd_L_02->frame_data_length == sizeof( frame_data_L_02 ) ); + memset( frame_data_L_02, 0x03, sizeof( frame_data_L_02 ) ); + uint8_t frame_data_R_02[SIZE_160]; + assert( ftd_R_02->frame_data_length == sizeof( frame_data_R_02 ) ); + memset( frame_data_R_02, 0x04, sizeof( frame_data_R_02 ) ); + uint8_t frame_data_L_03[SIZE_70]; + assert( ftd_L_03->frame_data_length == sizeof( frame_data_L_03 ) ); + memset( frame_data_L_03, 0x05, sizeof( frame_data_L_03 ) ); + uint8_t frame_data_R_03[SIZE_320]; + assert( ftd_R_03->frame_data_length == sizeof( frame_data_R_03 ) ); + memset( frame_data_R_03, 0x06, sizeof( frame_data_R_03 ) ); + uint8_t frame_data_L_04[SIZE_70]; + assert( ftd_L_04->frame_data_length == sizeof( frame_data_L_04 ) ); + memset( frame_data_L_04, 0x07, sizeof( frame_data_L_04 ) ); + uint8_t frame_data_R_04[SIZE_160]; + assert( ftd_R_04->frame_data_length == sizeof( frame_data_R_04 ) ); + memset( frame_data_R_04, 0x08, sizeof( frame_data_R_04 ) ); + memcpy( sender_ftds[0].frame_data, frame_data_L_01, sender_ftds[0].frame_data_length ); + memcpy( sender_ftds[1].frame_data, frame_data_R_01, sender_ftds[1].frame_data_length ); + memcpy( sender_ftds[2].frame_data, frame_data_L_02, sender_ftds[2].frame_data_length ); + memcpy( sender_ftds[3].frame_data, frame_data_R_02, sender_ftds[3].frame_data_length ); + memcpy( sender_ftds[4].frame_data, frame_data_L_03, sender_ftds[4].frame_data_length ); + memcpy( sender_ftds[5].frame_data, frame_data_R_03, sender_ftds[5].frame_data_length ); + memcpy( sender_ftds[6].frame_data, frame_data_L_04, sender_ftds[6].frame_data_length ); + memcpy( sender_ftds[7].frame_data, frame_data_R_04, sender_ftds[7].frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + + assert( payload_config.fdl_request == fdl_req ); + assert( payload_config.frame_duration_us == 5000 ); + assert( payload_config.high_resolution_enabled == 0 ); + assert( payload_config.sampling_rate_hz == 48000 ); + assert( payload_config.num_ftds == 8 ); + assert( payload_config.num_media_times == 4 ); + assert( payload_config.num_channels == 2 ); + for ( int32_t i = 0; i < payload_config.num_ftds; ++i ) + { + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].h == sender_ftds[i].h ); + assert( payload_config.ftds[i].fdi == sender_ftds[i].fdi ); + assert( payload_config.ftds[i].bwr == sender_ftds[i].bwr ); + assert( payload_config.ftds[i].fc == sender_ftds[i].fc ); + assert( payload_config.ftds[i].frame_data_length == sender_ftds[i].frame_data_length ); + assert( payload_config.ftds[i].frame_data != sender_ftds[i].frame_data ); + assert( 0 == memcmp( payload_config.ftds[i].frame_data, sender_ftds[i].frame_data, sender_ftds[i].frame_data_length ) ); + } + + free( receiverBuffer ); + return 0; +} + +static int try_unpack_invalid_values( void ) +{ + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + const LC3PLUS_RTP_FDL fdl_req = LC3PLUS_RTP_FDL_LENGTH_3_MAX; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = SIZE_70; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_req, sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_70]; + assert( ftd_L_01->frame_data_length == sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, sizeof( frame_data_L_01 ) ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + int32_t fdl_req_length; + error = LC3PLUS_RTP_frame_data_length_get_size( &fdl_req_length, fdl_req ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_frame_data_length_get_size error\n" ); + } + for ( int16_t packed_buffer_incorrect_size = 0; packed_buffer_incorrect_size < ( fdl_req_length + 2 + SIZE_70 ); ++packed_buffer_incorrect_size ) + { + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_incorrect_size ); + if ( error == LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed to detect error\n" ); + } + } + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + free( receiverBuffer ); + return 0; +} + +#define LC3PLUS_RTP_TEST_NUM_FTDS_UT 3 +static int pack_and_unpack_different_fdl_sizes( void ) +{ + int32_t iFtdUt; + LC3PLUS_RTP_FDL fdl_requests_ut[LC3PLUS_RTP_TEST_NUM_FTDS_UT]; + fdl_requests_ut[0] = LC3PLUS_RTP_FDL_LENGTH_1_MIN; + fdl_requests_ut[1] = LC3PLUS_RTP_FDL_LENGTH_2_MIN; + fdl_requests_ut[2] = LC3PLUS_RTP_FDL_LENGTH_3_MIN; + + for ( iFtdUt = 0; iFtdUt < LC3PLUS_RTP_TEST_NUM_FTDS_UT; ++iFtdUt ) + { + LC3PLUS_RTP_FTD sender_ftds[LC3PLUS_MAX_NUM_CODERS]; + int32_t sender_ftds_num = 0; + + LC3PLUS_RTP_FTD *ftd_L_01 = &sender_ftds[0]; + ftd_L_01->fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + ftd_L_01->fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + ftd_L_01->bwr = LC3PLUS_RTP_FTD_BWR_FB; + ftd_L_01->h = LC3PLUS_RTP_FTD_H_PRIMARY; + ftd_L_01->frame_data = NULL; + ftd_L_01->frame_data_length = fdl_requests_ut[iFtdUt]; + sender_ftds_num++; + + const size_t packed_buffer_capacity = LC3PLUS_MAX_BS_SIZE; + size_t packed_buffer_actual_size; + uint8_t packed_buffer[LC3PLUS_MAX_BS_SIZE]; + memset( packed_buffer, 0, packed_buffer_capacity ); + // prepare bitstream buffer headers & layout + LC3PLUS_RTP_ERR error = LC3PLUS_RTP_payload_serialize( packed_buffer, packed_buffer_capacity, &packed_buffer_actual_size, fdl_requests_ut[iFtdUt], sender_ftds, sender_ftds_num ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } + + // copy encoded frames into their expected memory locations + uint8_t frame_data_L_01[SIZE_600]; + assert( ftd_L_01->frame_data_length <= sizeof( frame_data_L_01 ) ); + memset( frame_data_L_01, 0x01, ftd_L_01->frame_data_length ); + + uint8_t *receiverBuffer = malloc( packed_buffer_actual_size ); + assert( NULL != receiverBuffer ); + memcpy( receiverBuffer, packed_buffer, packed_buffer_actual_size ); + + LC3PLUS_RTP_PAYLOAD payload_config; + error = LC3PLUS_RTP_payload_deserialize( &payload_config, receiverBuffer, packed_buffer_actual_size ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + free( receiverBuffer ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( error ), "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + assert( payload_config.fdl_request == fdl_requests_ut[iFtdUt] ); + assert( payload_config.ftds[0].frame_data_length == fdl_requests_ut[iFtdUt] ); + free( receiverBuffer ); + } + return 0; +} + +static int run_all_payload_tests( void ) +{ + if ( pack_and_unpack_payload_config_2ch_10ms_lc3plus_20ms_ivas() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( pack_and_unpack_payload_config_2ch_5ms_lc3plus_20ms_ivas() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( try_unpack_invalid_values() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + if ( pack_and_unpack_different_fdl_sizes() != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return 0; +} diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c deleted file mode 100644 index 5de57d3e9250127c269918dfdbf8492e3fd6a366..0000000000000000000000000000000000000000 --- a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c +++ /dev/null @@ -1,1953 +0,0 @@ -/****************************************************************************************************** - -(C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository. All Rights Reserved. - -This software is protected by copyright law and by international treaties. -The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, -Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., -Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, -Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other -contributors to this repository retain full ownership rights in their respective contributions in -the software. This notice grants no license of any kind, including but not limited to patent -license, nor is any license granted by implication, estoppel or otherwise. - -Contributors are required to enter into the IVAS codec Public Collaboration agreement before making -contributions. - -This software is provided "AS IS", without any express or implied warranties. The software is in the -development stage. It is intended exclusively for experts who have experience with such software and -solely for the purpose of inspection. All implied warranties of non-infringement, merchantability -and fitness for a particular purpose are hereby disclaimed and excluded. - -Any dispute, controversy or claim arising under or in relation to providing this software shall be -submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in -accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and -the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "ivas_lc3plus_enc.h" -#include "ivas_lc3plus_common.h" -#include "ivas_lc3plus_dec.h" -#include "ivas_error_utils.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT - -#define MAX_SAMPLES_PER_CHANNEL 960 - -/* included by ivas_lc3plus_unit_test.c */ - -typedef int ( *ScenarioFnPtr )( const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE dec, - uint8_t *bitstream_in, - int32_t bitstream_in_size, - float **pcm_out ); - -static int encodeAndDecodeOne6chFrameFixture( LC3PLUS_CONFIG config, const int16_t enableCaching, const int32_t bps, ScenarioFnPtr scenarioFn ) -{ - ivas_error err; - int32_t encDelay = -1; - int32_t decDelay = -1; - - IVAS_LC3PLUS_ENC_HANDLE encHandle; - err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - if ( encDelay == -1 || encDelay == 0 ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); - } - - /* encode one frame */ - int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); - float *pcm_in[6]; - float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch3[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch3, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch4[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch4, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch5[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch5, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_in_ch6[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_in_ch6, 0, numSamplesPerChannels * sizeof( float ) ); - pcm_in[0] = pcm_in_ch1; - pcm_in[1] = pcm_in_ch2; - pcm_in[2] = pcm_in_ch3; - pcm_in[3] = pcm_in_ch4; - pcm_in[4] = pcm_in_ch5; - pcm_in[5] = pcm_in_ch6; - - int32_t bitstreamSizePerIvasFrame = 0; - err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); - if ( IVAS_ERR_OK != err ) - return err; - - uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); - memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); - - err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); - if ( IVAS_ERR_OK != err ) - return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); - - /* decode one frame */ - IVAS_LC3PLUS_DEC_HANDLE decHandle; - err = IVAS_LC3PLUS_DEC_Open( config, -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING - enableCaching, -#endif - &decHandle ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - if ( decDelay == -1 || decDelay == 0 ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); - } - - uint8_t *bitstream_in = bitstream_out; - - float *pcm_out[6]; - float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch3[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch3, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch4[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch4, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch5[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch5, 0, numSamplesPerChannels * sizeof( float ) ); - float pcm_out_ch6[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; - memset( pcm_out_ch6, 0, numSamplesPerChannels * sizeof( float ) ); - pcm_out[0] = pcm_out_ch1; - pcm_out[1] = pcm_out_ch2; - pcm_out[2] = pcm_out_ch3; - pcm_out[3] = pcm_out_ch4; - pcm_out[4] = pcm_out_ch5; - pcm_out[5] = pcm_out_ch6; - - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - if ( NULL != scenarioFn ) - { - err = ( *scenarioFn )( config, decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - IVAS_LC3PLUS_DEC_Close( &decHandle ); - free( bitstream_out ); - - return 0; -} - -/* - * in: [dec, dec, dec, dec] - * expected out: [dec_and_use, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_decode_all_subframes( const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - // const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame == 0 ); - if(NULL != decHandle->bitstream_caches) - { - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - } - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct post decoding state */ - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -/* - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - */ -static int scenario_dont_decode_last_2_subframes( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - if(NULL != decHandle->bitstream_caches) - { - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - } - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * in: [dec, skip, skip, skip] - * expected out: [dec_and_use, skip, skip, cache] - */ -static int scenario_dont_decode_last_3_subframes( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 3 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last three subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframes before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 3 ) - { - /* subframes before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -/* - * in: [skip, dec, dec, dec] - * expected out: [dec_and_drop, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_skip_first_subframe( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if ( iSubframeIdx == 0 ) - { - /* skip the first subframe */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the following subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - - if ( iLc3plusFrame == 0 ) - { - /* first subframe is expected to be decoded and dropped */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [dec, dec, dec, dec] - * expected out: [dec_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_decode_cache( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2, ensure that the cache is used */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - /* decode all */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [skip, skip, dec, dec] - * expected out: [skip, dec_and_drop, dec_and_use, dec_and_use] - * - * Step2: - * in: [dec, dec, dec, dec] - * expected out: [no_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use] - */ -static int scenario_get_active_dont_cache( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * * expected out: [skip, dec_and_drop, dec_and_use, dec_and_use] */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 3 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2, ensure that there is no cache */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - /* decode all [dec, dec, dec, dec]*/ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct decoder actions - * expected out: [no_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use]*/ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [skip, dec, skip, dec] - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_drop, dec_and_use] - * */ -static int scenario_per_subframe_switches_skip_first( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [skip, dec, skip, dec] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else - { - //unsupported iSubframeIdx count; - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_drop, dec_and_use] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 1 || iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 0 || iLc3plusFrame == 2) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [dec, skip, dec, skip] - * expected out: [dec_cache & dec_and_use, dec_and_drop, dec_and_use, cache] - * */ -static int scenario_per_subframe_switches_dec_first( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [dec, skip, dec, skip] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [dec_cache & dec_and_use, dec_and_drop, dec_and_use, cache] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, skip] - * - * Step2: - * in: [dec, skip, dec, skip] - * expected out: [drop_cache & dec_and_use, skip, dec_and_use, skip] - * */ -static int scenario_per_subframe_switches_dec_first_no_caching( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [dec, skip, dec, skip] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [drop_cache & dec_and_use, skip, dec_and_use, skip] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( NULL == decHandle->bitstream_caches ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} -#endif - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [dec, skip, skip, dec] - * expected out: [dec_cache & dec_and_use, skip, dec_and_drop, dec_and_use] - * */ -static int scenario_per_subframe_bundle_switches_dec_first( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [dec, skip, skip, dec] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 0 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 1 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [dec_cache & dec_and_use, skip, dec_and_drop, dec_and_use] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - -/* - * Step1: - * in: [dec, dec, skip, skip] - * expected out: [dec_and_use, dec_and_use, skip, cache] - * - * Step2: - * in: [skip, dec, dec, skip] - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_use, cache] - * */ -static int scenario_per_subframe_bundle_switches_skip_first( - const LC3PLUS_CONFIG config, - IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ - uint8_t *bitstream_in, /* i: pointer to input bitstream */ - int32_t bitstream_in_size, /* i: size of bitstream_in */ - float **pcm_out /* o: decoded samples */ ) -{ - ivas_error err; - const int16_t decode = 1; - const int16_t skipDecoding = 0; - uint32_t iDec = 0; - int iLc3plusFrame = 0; - int lc3framesPerIvasFrame; - int16_t **selective_decoding_matrix; - err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* Set selective decoding scenario */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); - if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ - { - /* skip the last two subframes */ - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - /* decode the previous ones */ - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - } - } - - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) - { - /* last subframe is expected to be cached */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) - { - /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); - } - else - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - } - - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder caching */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - /* Step 2 - * in: [skip, dec, dec, skip] - * */ - for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) - { - for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) - { - if(iSubframeIdx == 1 || iSubframeIdx == 2) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = decode; - } - else if(iSubframeIdx == 0 || iSubframeIdx == 3) - { - selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; - } - else - { - // unsupported iSubframeIdx count - return 1; - } - - } - } - /* Apply selective decoding scenario */ - err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - - /* verify correct decoder actions - * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_use, cache] - * */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( iLc3plusFrame == 0 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); - } - else if ( iLc3plusFrame == 1 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 2 ) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - else if ( iLc3plusFrame == 3) - { - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); - } - else - { - assert(0); - } - } - } - err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); - if ( IVAS_ERR_OK != err ) - { - return err; - } - /* verify correct post-decoding state */ - lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; - for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) - { - assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); - assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); - assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ - assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); - } - } - - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); - return IVAS_ERR_OK; -} - - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_all_subframes( void ) -{ - int err; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_decode_all_subframes ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_2_subframes( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_dont_decode_last_2_subframes ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_3_subframes( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_dont_decode_last_3_subframes ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_skip_first_subframe( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_skip_first_subframe ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_cache( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_decode_cache ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_skip_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_skip_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_dec_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_dec_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_bundle_switches_dec_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_skip_first( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_bundle_switches_skip_first ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} - -#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first_no_caching( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 0; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_dec_first_no_caching ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} -#endif - -static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_get_active_dont_cache( void ) -{ - int err = 0; - LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; - const int16_t enableCaching = 1; - err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_get_active_dont_cache ); - if ( 0 != err ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); - } - return err; -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/scripts/split_rendering/lc3plus/split_rend_lc3plus_cmdlines.py b/scripts/split_rendering/lc3plus/split_rend_lc3plus_cmdlines.py deleted file mode 100755 index 033c25bb6027ab2752bf58c33ec9b70cdff50650..0000000000000000000000000000000000000000 --- a/scripts/split_rendering/lc3plus/split_rend_lc3plus_cmdlines.py +++ /dev/null @@ -1,191 +0,0 @@ -""" -Generate command lines for split rendering with LC3plus -""" - -import itertools -import os - -# Paths -ENC_PATH = "./IVAS_cod" -DEC_PATH = "./IVAS_dec" -REND_PATH = "./IVAS_rend" -TEMP_DIR = "tmp" - -# Config values to iterate over -ISM_CONFIGS_NUM_OBJECTS = [1, 2, 3, 4] -IVAS_BITRATES = [128000] -PRE_HEAD_ROT_FILES = [ - "Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20static.csv" -] -POST_HEAD_ROT_FILES = [ - "Workspace_msvc/trajectories/post-renderer_pose_files/post_0static.csv" -] -RENDER_CONFIG_FILES = [ - ####################################################### - # Alternative 2 - LC3plus with CLDFB pose correction - "Workspace_msvc/renderer_configs/split_renderer_config_768_1dof.txt", - "Workspace_msvc/renderer_configs/split_renderer_config_512_2dof.txt", - None, # Alternative 2 is the default when no rendering config file is given on command line - ####################################################### - # Alternative 3 - LC3plus with multi-stream (TD) pose correction - "Workspace_msvc/renderer_configs/split_renderer_config_768_1dof_tdposecorr.txt", - "Workspace_msvc/renderer_configs/split_renderer_config_1536_2dof_tdposecorr.txt", -] - - -def audio_for_ism(num_objects): - return f"scripts/testv/stv{num_objects}ISM48s.wav" - - -def metadata_for_ism(num_objects): - return f"scripts/testv/stvISM{num_objects}.csv" - - -def basename(file_path): - basename_w_ext = os.path.basename(file_path) - return os.path.splitext(basename_w_ext)[0] - - -# Full chain: IVAS_cod -> IVAS_dec -> IVAS_rend(post) -def full_chain( - num_objects, ivas_bitrate, pre_head_rot_file, render_config_file, post_head_rot_file -): - bs_name = f"{TEMP_DIR}/ism{num_objects}_b{ivas_bitrate}_full_chain.g192" - cod = [ - ENC_PATH, - "-ism", - str(num_objects), - *[metadata_for_ism(i + 1) for i in range(num_objects)], - str(ivas_bitrate), - "48", - audio_for_ism(num_objects), - bs_name, - ] - - render_config_infix = ( - f"##{basename(render_config_file)}" if render_config_file else "" - ) - split_bs_name = bs_name.replace( - ".g192", f"##{basename(pre_head_rot_file)}{render_config_infix}##split.bs" - ) - render_config_args = ( - ["-render_config", render_config_file] if render_config_file else [] - ) - dec = [ - DEC_PATH, - "-T", - pre_head_rot_file, - *render_config_args, - "SPLIT_BINAURAL", - "48", - bs_name, - split_bs_name, - ] - - binaural_output_name = split_bs_name.replace( - ".bs", f"##{basename(post_head_rot_file)}##binaural.wav" - ) - rend = [ - REND_PATH, - "-i", - split_bs_name, - "-if", - "BINAURAL_SPLIT_CODED", - "-of", - "BINAURAL", - "-fs", - "48", - "-tf", - post_head_rot_file, - "-o", - binaural_output_name, - ] - - return [cod, dec, rend] - - -# Renderer chain: IVAS_rend(pre) -> IVAS_rend(post) -def rend_chain(num_objects, pre_head_rot_file, render_config_file, post_head_rot_file): - render_config_infix = ( - f"##{basename(render_config_file)}" if render_config_file else "" - ) - split_bs_name = f"{TEMP_DIR}/ism{num_objects}_rend_chain##{basename(pre_head_rot_file)}{render_config_infix}##split.bs" - render_config_args = ( - ["-render_config", render_config_file] if render_config_file else [] - ) - pre = [ - REND_PATH, - "-i", - audio_for_ism(num_objects), - "-if", - f"ISM{num_objects}", - "-im", - *[metadata_for_ism(i + 1) for i in range(num_objects)], - "-of", - "BINAURAL_SPLIT_CODED", - "-fs", - "48", - *render_config_args, - "-tf", - pre_head_rot_file, - "-o", - split_bs_name, - ] - - binaural_output_name = split_bs_name.replace( - ".bs", f"##{basename(post_head_rot_file)}##binaural.wav" - ) - post = [ - REND_PATH, - "-i", - split_bs_name, - "-if", - "BINAURAL_SPLIT_CODED", - "-of", - "BINAURAL", - "-fs", - "48", - "-tf", - post_head_rot_file, - "-o", - binaural_output_name, - ] - - return [pre, post] - - -def print_command_list(list_of_lists): - for lst in list_of_lists: - print(" ".join(lst)) - print("") # newline - - -def main(): - print("\n##########################################") - print("# Full chain: enc -> dec -> rend(post)") - print("##########################################\n") - for args_full_chain in itertools.product( - # Ordering here must match argument order in function call below! - ISM_CONFIGS_NUM_OBJECTS, - IVAS_BITRATES, - PRE_HEAD_ROT_FILES, - RENDER_CONFIG_FILES, - POST_HEAD_ROT_FILES, - ): - print_command_list(full_chain(*args_full_chain)) - - print("\n##########################################") - print("# Renderer chain: rend(pre) -> rend(post)") - print("##########################################\n") - for args_rend_chain in itertools.product( - # Ordering here must match argument order in function call below! - ISM_CONFIGS_NUM_OBJECTS, - PRE_HEAD_ROT_FILES, - RENDER_CONFIG_FILES, - POST_HEAD_ROT_FILES, - ): - print_command_list(rend_chain(*args_rend_chain)) - - -if __name__ == "__main__": - main() diff --git a/scripts/strip_split_rendering.py b/scripts/strip_split_rendering.py index 16382b189c1d2278962e02b60a8ebd1b674155b8..6ddf3b5f551fea0011734ddf4812d53985b4a4cf 100644 --- a/scripts/strip_split_rendering.py +++ b/scripts/strip_split_rendering.py @@ -32,92 +32,3 @@ import glob import os - -# remove other split rendering files -sr_files_rend = [ - "lib_rend\\ivas_MSPred.c", - "lib_rend\\ivas_NoiseGen.c", - "lib_rend\\ivas_PerceptualModel.c", - "lib_rend\\ivas_PredDecoder.c", - "lib_rend\\ivas_PredEncoder.c", - "lib_rend\\ivas_RMSEnvGrouping.c", - "lib_rend\\ivas_lc3plus_common.c", - "lib_rend\\ivas_lc3plus_common.h", - "lib_rend\\ivas_lc3plus_dec.c", - "lib_rend\\ivas_lc3plus_dec.h", - "lib_rend\\ivas_lc3plus_enc.c", - "lib_rend\\ivas_lc3plus_enc.h", - "lib_rend\\ivas_lcld_decoder.c", - "lib_rend\\ivas_lcld_encoder.c", - "lib_rend\\ivas_lcld_prot.h", - "lib_rend\\ivas_lcld_rom_tables.c" - "lib_rend\\ivas_lcld_rom_tables.h" - "lib_rend\\ivas_splitRend_lcld_dec.c", - "lib_rend\\ivas_splitRend_lcld_enc.c", - "lib_rend\\ivas_splitRendererPLC.c", - "lib_rend\\ivas_splitRendererPost.c", - "lib_rend\\ivas_splitRendererPre.c", - "lib_rend\\ivas_splitRenderer_utils.c", -] - -sr_files_util = [ - "lib_util\\split_rend_bfi_file_reader.c", - "lib_util\\split_rend_bfi_file_reader.h", - "lib_util\\split_render_file_read_write.c", - "lib_util\\split_render_file_read_write.h", -] - -if __name__ == "__main__": - - wsfile = ".\Workspace_msvc\Workspace_msvc.sln" - rendproj = ".\Workspace_msvc\lib_rend.vcxproj" - utilproj = ".\Workspace_msvc\lib_util.vcxproj" - lc3proj = ".\Workspace_msvc\lib_lc3plus.vcxproj" - - # Remove lc3plus project - os.remove(lc3proj) - - # Patch Workspace_msvc.sln - with open(wsfile, "r") as f: - lines = f.readlines() - with open(wsfile, "w") as f: - skip = 0 - for line in lines: - if "lib_lc3plus.vcxproj" in line: - skip = 1 - else: - if skip == 0: - f.write(line) - else: - skip = skip - 1 - - # Patch lib_rend.vcxproj - with open(rendproj, "r") as f: - lines = f.readlines() - with open(rendproj, "w") as f: - skip = 0 - for line in lines: - if any([x in line for x in sr_files_rend]): - skip = 1 - if "lib_lc3plus.vcxproj" in line: - skip = 4 - if skip == 0: - f.write(line) - else: - skip = skip - 1 - - # Patch lib_util.vcxproj - with open(utilproj, "r") as f: - lines = f.readlines() - with open(utilproj, "w") as f: - for line in lines: - if not any([x in line for x in sr_files_util]): - f.write(line) - - # Remove include libraries - for proj in glob.glob(".\Workspace_msvc\*.vcxproj"): - with open(proj, "r") as f: - lines = f.readlines() - with open(proj, "w") as f: - for line in lines: - f.write(line.replace("..\lib_lc3plus;", "")) diff --git a/scripts/strip_split_rendering.sh b/scripts/strip_split_rendering.sh index 685974006c42a8372991f9716e23ccc627eac4ee..916f56e6174fdf845dcd81ce3d458801307e8870 100755 --- a/scripts/strip_split_rendering.sh +++ b/scripts/strip_split_rendering.sh @@ -31,61 +31,3 @@ # OUTDIR=$1 - - -# remove complete lc3plus folder -rm -R $OUTDIR/lib_lc3plus - -# remove other split rendering files -declare -a sr_files_rend=( - "lib_rend/ivas_MSPred.c" - "lib_rend/ivas_NoiseGen.c" - "lib_rend/ivas_PerceptualModel.c" - "lib_rend/ivas_PredDecoder.c" - "lib_rend/ivas_PredEncoder.c" - "lib_rend/ivas_RMSEnvGrouping.c" - "lib_rend/ivas_lc3plus_common.c" - "lib_rend/ivas_lc3plus_common.h" - "lib_rend/ivas_lc3plus_dec.c" - "lib_rend/ivas_lc3plus_dec.h" - "lib_rend/ivas_lc3plus_enc.c" - "lib_rend/ivas_lc3plus_enc.h" - "lib_rend/ivas_lcld_decoder.c" - "lib_rend/ivas_lcld_encoder.c" - "lib_rend/ivas_lcld_prot.h" - "lib_rend/ivas_lcld_rom_tables.c" - "lib_rend/ivas_lcld_rom_tables.h" - "lib_rend/ivas_splitRend_lcld_dec.c" - "lib_rend/ivas_splitRend_lcld_enc.c" - "lib_rend/ivas_splitRendererPLC.c" - "lib_rend/ivas_splitRendererPost.c" - "lib_rend/ivas_splitRendererPre.c" - "lib_rend/ivas_splitRenderer_utils.c" -) - -for file in ${sr_files_rend[@]}; do - rm $OUTDIR/$file - file_windows=${file//\//'\\'} - sed -i.bak -e "/${file_windows}/d" ${OUTDIR}/Workspace_msvc/lib_rend.vcxproj -done - -declare -a sr_files_util=( - "lib_util/split_rend_bfi_file_reader.c" - "lib_util/split_rend_bfi_file_reader.h" - "lib_util/split_render_file_read_write.c" - "lib_util/split_render_file_read_write.h" -) - -for file in ${sr_files_util[@]}; do - rm $OUTDIR/$file - file_windows=${file//\//'\\'} - sed -i.bak -e "/${file_windows}/d" ${OUTDIR}/Workspace_msvc/lib_util.vcxproj -done - -# delete project file -rm ${OUTDIR}/Workspace_msvc/lib_lc3plus.vcxproj - -# patch project/solution files -sed -i.bak "/lib_lc3plus.vcxproj/,+1d" ${OUTDIR}/Workspace_msvc/Workspace_msvc.sln -find ${OUTDIR}/Workspace_msvc -name "*.vcxproj" -exec sed -i.bak -e "s/..\\lib_lc3plus\;//g" \{\} \; -sed -i.bak "/lib_lc3plus.vcxproj/,+3d" ${OUTDIR}/Workspace_msvc/lib_rend.vcxproj # patch dependency diff --git a/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_16kHz.bin b/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_16kHz.bin deleted file mode 100644 index ad94d8a930b76924dd1bf81d5ad740c2b85b8633..0000000000000000000000000000000000000000 --- a/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_16kHz.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8bb531aa8b9c7d0ab5fbc90e183dc58886b2751ca831aae4088d3d244a6c424a -size 167368 diff --git a/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_32kHz.bin b/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_32kHz.bin deleted file mode 100644 index b0090299d11a794427878d37a859a1998fe6461b..0000000000000000000000000000000000000000 --- a/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_32kHz.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4d23072cbae281edcf6cacd7d7099dfb6a28324b069e4572d868a16dc37ec41b -size 329048 diff --git a/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_48kHz.bin b/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_48kHz.bin deleted file mode 100644 index 08ecb4c98be61da868037beb44a65349100725f1..0000000000000000000000000000000000000000 --- a/scripts/td_object_renderer/hrtf_data/IVAS_default/hrfilter_model_v003_48kHz.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65a57c54ef0f5d5affb6e2a785a0570511baea3426acb0486a9cae2fbfc95370 -size 486968 diff --git a/scripts/td_object_renderer/modeling_tool/Gen_Hrf_IVAS_Binary.m b/scripts/td_object_renderer/modeling_tool/Gen_Hrf_IVAS_Binary.m index 35d659174d395bd272b9454c21f935caffa4766b..d25700ad76b7793a8867114d015bb4efb0099adc 100644 --- a/scripts/td_object_renderer/modeling_tool/Gen_Hrf_IVAS_Binary.m +++ b/scripts/td_object_renderer/modeling_tool/Gen_Hrf_IVAS_Binary.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function Gen_Hrf_IVAS_Binary(dataSpec, modSpec, info) @@ -111,7 +115,7 @@ if dataSpec.genRomFile ' *------------------------------------------------------------------------*/' '/* TD renderer default HRIR model */' 'extern const float defaultHRIR_rom_latency_s;' - ['extern const int16_t defaultHRIR_rom_azimDim2[' int2str(size(mod_hrf_org.elevBf{1}, 3)) '];'] + ['extern const int16_t defaultHRIR_rom_model_configuration[6];'] ['extern const int16_t defaultHRIR_rom_azimDim3[' int2str(size(mod_hrf_org.elevBf{1}, 3)) '];'] ['extern const int16_t defaultHRIR_rom_azim_start_idx[' int2str(size(mod_hrf_org.elevBf{1}, 3)) '];'] 'extern const int16_t defaultHRIR_rom_azimSegSamples[1];' @@ -372,20 +376,14 @@ for fs = [48000 32000 16000] fwrite(fileID, fs_khz, 'short'); % General - model-specific parts - fwrite(fileID, size(mod_hrf.elevBf{1}, 1), 'short'); % N = 4 i.e. coefficients for cubic including zeroth order fwrite(fileID, size(mod_hrf.WR{1}, 2), 'short'); % K, filter length % Elevation model structure - elevDim2 = size(mod_hrf.elevBf{1}, 2); elevDim3 = size(mod_hrf.elevBf{1}, 3); - fwrite(fileID, elevDim2, 'short'); % elevDim2 fwrite(fileID, elevDim3, 'short'); % elevDim3 = P fwrite(fileID, mod_hrf.elevKSeq{1}, 'float'); % length = elevDim3-2 % Azimuth model structure azim_start_idx = 0; - c_file_content_dim2 = { - ['const int16_t defaultHRIR_rom_azimDim2[' num2str(elevDim3) '] = {'] - }; c_file_content_dim3 = { ['const int16_t defaultHRIR_rom_azimDim3[' num2str(elevDim3) '] = {'] }; @@ -399,8 +397,6 @@ for fs = [48000 32000 16000] for i = 1:elevDim3 azimDim2 = size(mod_hrf.azimBf{i}, 2); azimDim3 = size(mod_hrf.azimBf{i}, 3); - fwrite(fileID, azimDim2, 'short'); % azimDim2 - content_dim2 = [content_dim2 int2str(azimDim2) ', ']; fwrite(fileID, azimDim3, 'short'); % azimDim3 = Q content_dim3 = [content_dim3 int2str(azimDim3) ', ']; fwrite(fileID, azim_start_idx, 'short'); % start azim index per elevation @@ -410,9 +406,6 @@ for fs = [48000 32000 16000] end if fs == fs_orig && dataSpec.genRomFile fileID_c = fopen(c_file_name,'at'); - c_file_content_dim2{size(c_file_content_dim2,2)+1} = content_dim2; - c_file_content_dim2{size(c_file_content_dim2,2)+1} = '};'; - c_file_content_dim2{size(c_file_content_dim2,2)+1} = ''; c_file_content_dim3{size(c_file_content_dim3,2)+1} = content_dim3; c_file_content_dim3{size(c_file_content_dim3,2)+1} = '};'; c_file_content_dim3{size(c_file_content_dim3,2)+1} = ''; @@ -420,14 +413,64 @@ for fs = [48000 32000 16000] c_file_content_start_idx{size(c_file_content_start_idx,2)+1} = '};'; c_file_content_start_idx{size(c_file_content_start_idx,2)+1} = ''; - c_file_content = string(join(c_file_content_dim2,newline)); + c_file_content = ... + ['const int16_t defaultHRIR_rom_model_configuration[6] = {' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(useITD) ', /* UseItdModel */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(elevDim3) ', /* elevDim3 */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(size(mod_hrf_org.WL{1}, 1)) ', /* AlphaN */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(num_unique_splines) ', /* num_unique_azim_splines */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(e_num_points) ', /* elevSegSamples */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(size(mod_hrf_org.WL{1}, 2)) ', /* K_48k */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = ['};' newline ]; + fprintf(fileID_c,'%s', c_file_content); + + arr_str = join(mat2str((single(len_e)))); + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + c_file_content = ... + ['const int16_t defaultHRIR_rom_elevBsLen[' num2str(length(len_e)) '] = {' newline ... + arr_str ... + newline '};' newline ... + ]; fprintf(fileID_c,'%s', c_file_content); + + arr_str = join(mat2str((single(start_e)))); + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + c_file_content = ... + ['const int16_t defaultHRIR_rom_elevBsStart[' num2str(length(start_e)) '] = {' newline ... + arr_str ... + newline '};' newline ... + ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = string(join(c_file_content_dim3,newline)); fprintf(fileID_c,'%s', c_file_content); c_file_content = string(join(c_file_content_start_idx,newline)); fprintf(fileID_c,'%s', c_file_content); - - c_file_content = ['const int16_t defaultHRIR_rom_azimSegSamples[1] = {' newline num2str(mod_hrf_org.azimKmSeq{1,2}(2)) ',' newline '};' newline]; + + + arr_str = join(mat2str((single(a_num_points(1:num_unique_splines))))); + if(num_unique_splines>1) + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + else + arr_str(end+1) = ','; + end + c_file_content = ['const int16_t defaultHRIR_rom_azimSegSamples[' num2str(num_unique_splines) '] = {' newline arr_str newline '};' newline]; fprintf(fileID_c,'%s', c_file_content); arr_str = mat2str(azimShapeIdx); @@ -662,20 +705,15 @@ for fs = [48000 32000 16000] % If ITD model is used, parameters are stored in 2nd part of the same file if useITD % General - fwrite(fileID, size(mod_itd.elevBf, 1), 'short'); % N = 4 i.e. coefficients for cubic including zeroth order %fwrite(fileID, size(mod_itd.W, 2), 'short'); % K = 1 always for ITD, so do not need to write. % Elevation model structure - elevDim2 = size(mod_itd.elevBf, 2); elevDim3 = size(mod_itd.elevBf, 3); - fwrite(fileID, elevDim2, 'short'); % elevDim2 fwrite(fileID, elevDim3, 'short'); % elevDim3 = P fwrite(fileID, mod_itd.elevKSeq, 'float'); % length = elevDim3-2 % Azimuth model structure - azimDim2 = size(mod_itd.azimBf{2}, 2); azimDim3 = size(mod_itd.azimBf{2}, 3); - fwrite(fileID, azimDim2, 'short'); % azimDim2 fwrite(fileID, azimDim3, 'short'); % azimDim3 = Q fwrite(fileID, mod_itd.azimKSeq{2}, 'float'); % length = azimDim3+1 @@ -725,6 +763,68 @@ for fs = [48000 32000 16000] c_file_content = [ arr_str newline '};' newline]; fprintf(fileID_c,'%s', c_file_content); + c_file_content = ... + ['const int16_t defaultHRIR_rom_ITD_model_configuration[4] = {' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(elevDim3) ', /* elevDim3 */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(azimDim3) ', /* azimDim3 */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(e_num_points_ITD) ', /* elevSegSamples */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = [ num2str(a_num_points_ITD) ', /* azimSegSamples */' newline ]; + fprintf(fileID_c,'%s', c_file_content); + c_file_content = ['};' newline ]; + fprintf(fileID_c,'%s', c_file_content); + + arr_str = join(mat2str((single(len_e_ITD)))); + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + c_file_content = ... + ['const int16_t defaultHRIR_rom_ITD_elevBsLen[' num2str(length(len_e_ITD)) '] = {' newline ... + arr_str ... + newline '};' newline ... + ]; + fprintf(fileID_c,'%s', c_file_content); + + arr_str = join(mat2str((single(start_e_ITD)))); + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + c_file_content = ... + ['const int16_t defaultHRIR_rom_ITD_elevBsStart[' num2str(length(start_e_ITD)) '] = {' newline ... + arr_str ... + newline '};' newline ... + ]; + fprintf(fileID_c,'%s', c_file_content); + + arr_str = join(mat2str((single(len_a_ITD)))); + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + c_file_content = ... + ['const int16_t defaultHRIR_rom_ITD_azimBsLen[' num2str(length(len_a_ITD)) '] = {' newline ... + arr_str ... + newline '};' newline ... + ]; + fprintf(fileID_c,'%s', c_file_content); + + arr_str = join(mat2str((single(start_a_ITD)))); + arr_str = arr_str(2:end); + arr_str(end) = ';'; + arr_str = replace(arr_str, ";",','); + arr_str = replace(arr_str, " ",', '); + c_file_content = ... + ['const int16_t defaultHRIR_rom_ITD_azimBsStart[' num2str(length(start_a_ITD)) '] = {' newline ... + arr_str ... + newline '};' newline ... + ]; + fprintf(fileID_c,'%s', c_file_content); + arr_str_all = num2hex(single(azimSplineShapeITD_all)); numCol = 25; numIter = floor(length(azimSplineShapeITD_all)/numCol); @@ -809,6 +909,8 @@ end % fs loop if dataSpec.genRomFile h_file_content = string(join({'' + ['extern const int16_t defaultHRIR_rom_elevBsLen[' int2str(length(len_e)) '];'] + ['extern const int16_t defaultHRIR_rom_elevBsStart[' int2str(length(start_e)) '];'] ['extern const uint32_t defaultHRIR_rom_elevBsShape[' int2str(length(elevSplineShape_all)) '];'] ['extern const uint32_t defaultHRIR_rom_azimBsShape[' int2str(length(azimSplineShape{1})) '];'] ['extern const uint32_t defaultHRIR_rom_ITD_W[' int2str(mod_itd.angleBfNum) '];'] @@ -816,6 +918,11 @@ if dataSpec.genRomFile ['extern const float defaultHRIR_rom_ITD_azimKSeq[19];'] ['extern const uint32_t defaultHRIR_rom_ITD_elevBsShape[' int2str(length(elevSplineShapeITD_all)) '];'] ['extern const float defaultHRIR_rom_ITD_elevKSeq[16];'] + ['extern const int16_t defaultHRIR_rom_ITD_model_configuration[4];'] + ['extern const int16_t defaultHRIR_rom_ITD_elevBsLen[' int2str(length(len_e_ITD)) '];'] + ['extern const int16_t defaultHRIR_rom_ITD_elevBsStart[' int2str(length(start_e_ITD)) '];'] + ['extern const int16_t defaultHRIR_rom_ITD_azimBsLen[' int2str(length(len_a_ITD)) '];'] + ['extern const int16_t defaultHRIR_rom_ITD_azimBsStart[' int2str(length(start_a_ITD)) '];'] '#endif' '' }, newline)); diff --git a/scripts/td_object_renderer/modeling_tool/HrfModBsp_Config.m b/scripts/td_object_renderer/modeling_tool/HrfModBsp_Config.m index 87eb2a4bb8f9f43c44699ce500944826a61817a7..cef47b278626a714fbd44418ec4c986d5d28692e 100644 --- a/scripts/td_object_renderer/modeling_tool/HrfModBsp_Config.m +++ b/scripts/td_object_renderer/modeling_tool/HrfModBsp_Config.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [dataSpec, modSpec] = HrfModBsp_Config(dataSpec) %% HRF directory diff --git a/scripts/td_object_renderer/modeling_tool/HrfModBsp_InitPath.m b/scripts/td_object_renderer/modeling_tool/HrfModBsp_InitPath.m index 2f604d4ef032768648922c6bf62bc7efb7124222..2c3f621328176822bdde9fefc56ef453ddc81e53 100644 --- a/scripts/td_object_renderer/modeling_tool/HrfModBsp_InitPath.m +++ b/scripts/td_object_renderer/modeling_tool/HrfModBsp_InitPath.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function HrfModBsp_InitPath(dataSpec) % Initialize Matlab paths diff --git a/scripts/td_object_renderer/modeling_tool/Mod_Hrf_Itd_Main.m b/scripts/td_object_renderer/modeling_tool/Mod_Hrf_Itd_Main.m index ad84430e3808913efc2e64856b250558f56f4a2d..534a438a2911a3488b70d8768ae1c3bb9716c410 100644 --- a/scripts/td_object_renderer/modeling_tool/Mod_Hrf_Itd_Main.m +++ b/scripts/td_object_renderer/modeling_tool/Mod_Hrf_Itd_Main.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function Mod_Hrf_Itd_Main( varargin ) clc diff --git a/scripts/td_object_renderer/modeling_tool/evaluation/HrfModBspTdFir_InterpHrf.m b/scripts/td_object_renderer/modeling_tool/evaluation/HrfModBspTdFir_InterpHrf.m index 2e69140c492ebeb18f63b385ffc5c43dd010d3a7..fc708e7c8d26e9e370714662d9f08df3eb9a60ec 100644 --- a/scripts/td_object_renderer/modeling_tool/evaluation/HrfModBspTdFir_InterpHrf.m +++ b/scripts/td_object_renderer/modeling_tool/evaluation/HrfModBspTdFir_InterpHrf.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function hrfHat = HrfModBspTdFir_InterpHrf(interp, elev, azim) diff --git a/scripts/td_object_renderer/modeling_tool/evaluation/evaluation_BspTdFir.m b/scripts/td_object_renderer/modeling_tool/evaluation/evaluation_BspTdFir.m index 5b1c068d1bb056998e3d6121c57d67689a59307a..8faa413e5e9c14d9a6bdffcfa29581dc487c7a2b 100644 --- a/scripts/td_object_renderer/modeling_tool/evaluation/evaluation_BspTdFir.m +++ b/scripts/td_object_renderer/modeling_tool/evaluation/evaluation_BspTdFir.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% classdef evaluation_BspTdFir < handle diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngCircFun.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngCircFun.m index 50c364b1b98981303b0e0cd713c765a27bb79d4d..5f113c48915e8c88083abc842e9dcb3ae03b6c63 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngCircFun.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngCircFun.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [Bf, kmSeq] = BSplineAngCircFun( P, kSeq ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngFun.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngFun.m index 847e20047e44cf63f66472c64c8bbec44aa6ddb7..d831c54d7d2ac61bbc0d65ada31bcdbe52187a8b 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngFun.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineAngFun.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [Bf, kmSeq] = BSplineAngFun( P, kSeq ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineFunc.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineFunc.m index 6a5e94f7370ec491dafa0cea6882bb6fa9af37f5..9755423b77fa897ff8141f2e72168caacb86b582 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineFunc.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineFunc.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function Bf = BSplineFunc( P, kmSeq ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineItdFun.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineItdFun.m index 5e48ec60c68ab9aca61c626449743e09919f3baf..3f72fe33aa114bfc3fbd88655db0d622c6097caf 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineItdFun.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineItdFun.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [Bf, kmSeq] = BSplineItdFun( P, kSeq ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_HrfInterpTdFir.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_HrfInterpTdFir.m index 63eb1b4ffdacb4fe028c6f69ce05458d6f0e5a40..30f866fa5be8ebf731fa6a4798f2ce1ee197cc41 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_HrfInterpTdFir.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_HrfInterpTdFir.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function interp = BSplineLSMod_HrfInterpTdFir( dat, mod, interp, flag ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_ItdInterpTdFir.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_ItdInterpTdFir.m index 5722bb0e0b1a0c726f893f19dd27f270f7512949..7917b4b53130dd19b447e622a4b128680ad3d59c 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_ItdInterpTdFir.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineLSMod_ItdInterpTdFir.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function interp = BSplineLSMod_ItdInterpTdFir( dat, mod, interp ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineRemoveZeroBasis.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineRemoveZeroBasis.m index d39e02e66ac6bfc449a25ddfbf449c52888f1689..20b7b2aecbd17464d1ed0db3a5913d84714246fe 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineRemoveZeroBasis.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineRemoveZeroBasis.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function Bf = BSplineRemoveZeroBasis( Bf ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampMat.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampMat.m index 01598215e51bc2ca3b0b4425b4b0e8e345b97975..658d30c78022e6b262002f5529c1f98d1bc276cf 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampMat.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampMat.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function BfMat = BSplineSampMat( Bf, kmSeq, sampVec) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVec.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVec.m index 9a4e519e57b90de984d22523f2e9e547ea1c5caf..d7c0c604c3efb5b95c3667b0cd9e68bf080aa01f 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVec.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVec.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function BfVec = BSplineSampVec( Bf, kmSeq, t) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVecITD.m b/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVecITD.m index 67717ada325a4c0206b2fb721c7c10489f0b401f..b46f4a6f8b95a79c8aa48b490ca847a597bdc1da 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVecITD.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/BSplineSampVecITD.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function BfVec = BSplineSampVecITD( Bf, kmSeq, t) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/Mod_Hrf_Itd.m b/scripts/td_object_renderer/modeling_tool/modeling/Mod_Hrf_Itd.m index fbeefcc30b79de16d3b9d0b72f86b76a39573555..decd39cb0586cd00c4d1b104c7e1abb18ef2dc24 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/Mod_Hrf_Itd.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/Mod_Hrf_Itd.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [mod, evalHrf, info] = Mod_Hrf_Itd(dataSpec, modSpec) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/SplitAngleData.m b/scripts/td_object_renderer/modeling_tool/modeling/SplitAngleData.m index 58c0c971bc5fa2657c9f6810c51ed65159e1a471..9d997896ef56f38001a79ef3797afd974a76ca99 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/SplitAngleData.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/SplitAngleData.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function split = SplitAngleData( trainSetSpec, dat ) diff --git a/scripts/td_object_renderer/modeling_tool/modeling/frac_delay.m b/scripts/td_object_renderer/modeling_tool/modeling/frac_delay.m index ced912f83f3b85eba7630b4825d34d0034978335..6f473926015d8186266e9b8c8ee25a2dbd9572bd 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/frac_delay.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/frac_delay.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function y = frac_delay(x,d,out_len,h_len) % Fractional delay diff --git a/scripts/td_object_renderer/modeling_tool/modeling/modeling_BspTdFir.m b/scripts/td_object_renderer/modeling_tool/modeling/modeling_BspTdFir.m index 3a39357c3a52b1f904d5e430cfa731d84ec058d2..71a91ccd0c8415e3165b43aa54b493bd73ff83b1 100644 --- a/scripts/td_object_renderer/modeling_tool/modeling/modeling_BspTdFir.m +++ b/scripts/td_object_renderer/modeling_tool/modeling/modeling_BspTdFir.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% classdef modeling_BspTdFir < handle % MODELING creates a modeling object which can be used to diff --git a/scripts/td_object_renderer/modeling_tool/preprocessing/EstDelay.m b/scripts/td_object_renderer/modeling_tool/preprocessing/EstDelay.m index d31b89c617e7872aa8c2f4cc51ba6d1a62c8decf..e6344345d4623d21d1cceb5f531cb6179a307bab 100644 --- a/scripts/td_object_renderer/modeling_tool/preprocessing/EstDelay.m +++ b/scripts/td_object_renderer/modeling_tool/preprocessing/EstDelay.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function delay = EstDelay( left, right ) % Estimate delay diff --git a/scripts/td_object_renderer/modeling_tool/preprocessing/data_SOFA.m b/scripts/td_object_renderer/modeling_tool/preprocessing/data_SOFA.m index bf8763c943b9029d64f4db2ed316d2ff72f62227..974ccf2ab59795e420a7e790d0331ecf83b0c40a 100644 --- a/scripts/td_object_renderer/modeling_tool/preprocessing/data_SOFA.m +++ b/scripts/td_object_renderer/modeling_tool/preprocessing/data_SOFA.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% classdef data_SOFA < handle diff --git a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalElevAzimSet.m b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalElevAzimSet.m index 27b17bace094f186398b076682480ad21d669be8..536b8469aeaf9bc5c3abfc1ab45745f64ccb2545 100644 --- a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalElevAzimSet.m +++ b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalElevAzimSet.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function elevAzimSet = SpatArea_EvalElevAzimSet( elevSeq, azimSeq ) diff --git a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalInnProdWeights.m b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalInnProdWeights.m index 0a8ef73336ee13f1b8725e82d878b18a487696c5..a575bc4b5c0762f5da5f3a6928e6e34b9028d68a 100644 --- a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalInnProdWeights.m +++ b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalInnProdWeights.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function innProdWeightSet = SpatArea_EvalInnProdWeights( spatAreaSet, elevAzimSet ) diff --git a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSetDistr.m b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSetDistr.m index 568df7d4f5e3d6723d8458efe33ba6b590b73373..b1c7de874db7b9c372686dbcb2dc691221430328 100644 --- a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSetDistr.m +++ b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSetDistr.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function theSet = SpatArea_EvalSetDistr( theSet ) diff --git a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSpatArea.m b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSpatArea.m index 83bef9a543a8930a65cb417e6a421fefb0b602e2..34944091ee5e56a09cbd91acab49841a0e132b6a 100644 --- a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSpatArea.m +++ b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalSpatArea.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function spatAreaSet = SpatArea_EvalSpatArea( evalAzimSet ) diff --git a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalTrainTestSets.m b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalTrainTestSets.m index a85e3fc4c2ac24d9935d8c8ebb8b6593efafb825..01afbedba8c7e497b65bbfdb4f4ecea09eace038 100644 --- a/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalTrainTestSets.m +++ b/scripts/td_object_renderer/modeling_tool/spat_area/SpatArea_EvalTrainTestSets.m @@ -1,3 +1,5 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, % Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., % Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, @@ -25,6 +27,8 @@ % 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function split = SpatArea_EvalTrainTestSets( split, spatAreaSet, ... elevAzimSet ) diff --git a/scripts/testv/stv2OA16c_cut.wav b/scripts/testv/stv2OA16c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..ff5d903c04803709f75d6f0ff5a871f16ba5579c --- /dev/null +++ b/scripts/testv/stv2OA16c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:603bcfa3fdaf1cb7e73b7c9da7017b37680d85162b7494177be3cffed61d4231 +size 1440044 diff --git a/scripts/testv/stv2OA16c_cut_.004.wav b/scripts/testv/stv2OA16c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..d5180c44b05f23c78a354780964bef7e9c49e34a --- /dev/null +++ b/scripts/testv/stv2OA16c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a08210deb9d2585838ad27b41e22b769b3e54cc8d5bfe15229520e19bf3098dc +size 1440044 diff --git a/scripts/testv/stv2OA16c_cut_16.0.wav b/scripts/testv/stv2OA16c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..18a826bf09c3e990d2c6ce4fad8c707bc8e28a90 --- /dev/null +++ b/scripts/testv/stv2OA16c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f8012db61a4be19a12d074b94a7a1b6ce15c71e0f84daabbfaae18aa97700c3 +size 1440044 diff --git a/scripts/testv/stv2OA32c_cut.wav b/scripts/testv/stv2OA32c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..7e5c6aae8927219d3a6c154f2f70ac323a4c7fc7 --- /dev/null +++ b/scripts/testv/stv2OA32c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:038b5280a4c975ae3b6206d9b69ff513493f975d41c71d04a95209960e7a629b +size 2880044 diff --git a/scripts/testv/stv2OA32c_cut_.004.wav b/scripts/testv/stv2OA32c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..3f8956143d7b44308cc77c550edb8f13c54bca9f --- /dev/null +++ b/scripts/testv/stv2OA32c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db2a43841dbbd87cc152d7e703e53da77059ca8f52e92030990b2d884aaeea57 +size 2880044 diff --git a/scripts/testv/stv2OA32c_cut_16.0.wav b/scripts/testv/stv2OA32c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..5f0d85863c42f911023172373b4fbd76d11b9e82 --- /dev/null +++ b/scripts/testv/stv2OA32c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f287429064e1a79f9f2c0b1d2bf0e6a8badc6224e9b12b67cd30975b1224cf4b +size 2880044 diff --git a/scripts/testv/stv2OA48c_cut.wav b/scripts/testv/stv2OA48c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..eb8d0a3f6256ac01da679cb24cac88de01fcc1a9 --- /dev/null +++ b/scripts/testv/stv2OA48c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df84bfe267d016665865ef1eced65c0150afb9b9a4890efd86ffbb87be36668e +size 4320044 diff --git a/scripts/testv/stv2OA48c_cut_.004.wav b/scripts/testv/stv2OA48c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..af076a2ccc4eeba12e2235a6dd58db9a4096bc6c --- /dev/null +++ b/scripts/testv/stv2OA48c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f1b7acc2b75144f970c0a158ae1706365c8247dec14ad43967360f1abf5c09a +size 4320044 diff --git a/scripts/testv/stv2OA48c_cut_16.0.wav b/scripts/testv/stv2OA48c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..5ce1e0b7338bc1e29030b4998d5399a5dc336100 --- /dev/null +++ b/scripts/testv/stv2OA48c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07d7bd51701997a3301ccee71e421c422388b8a076cc8b0b23b169da55a4b1b3 +size 4320044 diff --git a/scripts/testv/stv3OA16c_cut.wav b/scripts/testv/stv3OA16c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..0a2952b90c35929140911dd0fdbab05d9fbaab91 --- /dev/null +++ b/scripts/testv/stv3OA16c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35950b5b10ca76e910ae5294ee108d4d5b5fd1404aa69f678b035dd24438172e +size 2560044 diff --git a/scripts/testv/stv3OA16c_cut_.004.wav b/scripts/testv/stv3OA16c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..258b0b6d0bb7b1d0f994b294eaf8781946d0b078 --- /dev/null +++ b/scripts/testv/stv3OA16c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97fdb3191b17a60372f8f71d923f2bd0365c239a3ed5b9ff5a35a0cb94a2002f +size 2560044 diff --git a/scripts/testv/stv3OA16c_cut_16.0.wav b/scripts/testv/stv3OA16c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..f835fb1c0c7e620a1483e5937071c2b013620bb5 --- /dev/null +++ b/scripts/testv/stv3OA16c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:377e348577a95275dfc6741a30693678c462726968d07557e456d3bd709674f0 +size 2560044 diff --git a/scripts/testv/stv3OA32c_cut.wav b/scripts/testv/stv3OA32c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..9839a146f0f630cd8739190bede6cc34fe7a8089 --- /dev/null +++ b/scripts/testv/stv3OA32c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:841d1c86539c0842013c9ad3a562bdcc0d69ebd5c41f8655536898bbb7e79d35 +size 5120044 diff --git a/scripts/testv/stv3OA32c_cut_.004.wav b/scripts/testv/stv3OA32c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..6ed3da7e3b60fcc27dfa7753a6aba1cb3b4f289f --- /dev/null +++ b/scripts/testv/stv3OA32c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4536b7f93ab6e12e1714ce419af8c7477790b71d0372bb430c9a2d46424cbdcc +size 5120044 diff --git a/scripts/testv/stv3OA32c_cut_16.0.wav b/scripts/testv/stv3OA32c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..db3f20c704a0d54ba5c8fa01730575bbc9f81757 --- /dev/null +++ b/scripts/testv/stv3OA32c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04cc8770deaf7899966ea1b94aa290a5a4ae2c712c85c51805ee2a6eeb409a2b +size 5120044 diff --git a/scripts/testv/stv3OA48c_cut.wav b/scripts/testv/stv3OA48c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..6be77fbd8abdfbb83ffed106a4b1b7b821e0183f --- /dev/null +++ b/scripts/testv/stv3OA48c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd905c085de10ea6cb3e753eae5a053082909a0022364c2a22b6ddc3319cbd8e +size 7680044 diff --git a/scripts/testv/stv3OA48c_cut_.004.wav b/scripts/testv/stv3OA48c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..0a7a771757620bcd8736f6f832a62ef6c6304173 --- /dev/null +++ b/scripts/testv/stv3OA48c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:794c7cf7321d0e9c811358195f9bc8d28ba564ff22a6af587376c83b46361c22 +size 7680044 diff --git a/scripts/testv/stv3OA48c_cut_16.0.wav b/scripts/testv/stv3OA48c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..8e3f436df267aea79b75c6c0355e196edebd6197 --- /dev/null +++ b/scripts/testv/stv3OA48c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:232f2d173e864ac3843197e2d6c291881980aa22710aa0a16f518b5684d25ae4 +size 7680044 diff --git a/scripts/testv/stv51MC32c.wav b/scripts/testv/stv51MC32c.wav new file mode 100644 index 0000000000000000000000000000000000000000..62cfd81f0ca91a661d13ed246d909700bddc508e --- /dev/null +++ b/scripts/testv/stv51MC32c.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:956c9d6995aab480c605e249663334bb2a895cf3a2f108df803f1a5084aac5fc +size 7680132 diff --git a/scripts/testv/stvFOA16c_cut.wav b/scripts/testv/stvFOA16c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..6529a74cf3310ea7d2208b4ebe3ed174b11e8ba5 --- /dev/null +++ b/scripts/testv/stvFOA16c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7cefe32372f32cf518486b4dd5bdb599a34a877b5822152d62777d0be723cffd +size 640044 diff --git a/scripts/testv/stvFOA16c_cut_.004.wav b/scripts/testv/stvFOA16c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..9d07f0d7d45e915527e38d9c2558520220e01e8d --- /dev/null +++ b/scripts/testv/stvFOA16c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56c7fe054cb42b39ba8e4ff67d00adcf0fe82edfcdaf58179380708ea9dc760b +size 640044 diff --git a/scripts/testv/stvFOA16c_cut_16.0.wav b/scripts/testv/stvFOA16c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..7ede9f26929a35a7e4d3381d05fb8fa7f1e7f39d --- /dev/null +++ b/scripts/testv/stvFOA16c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23c1baac936d4ee00304b8da8847fc201bf5658827bf5155038ea73dd50048ce +size 640044 diff --git a/scripts/testv/stvFOA32c_cut.wav b/scripts/testv/stvFOA32c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..1fc25fcd6263d5d0f2df5b4452817782334ee7c8 --- /dev/null +++ b/scripts/testv/stvFOA32c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e204055ee1daeecc715f8d167532ba6b49b022c7671487f6abcadca0fc33bea +size 1280044 diff --git a/scripts/testv/stvFOA32c_cut_.004.wav b/scripts/testv/stvFOA32c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..a122bc20984b312240b27e2eb9e14f5f9cf1b1b1 --- /dev/null +++ b/scripts/testv/stvFOA32c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55037196717e4e8f0f4b532381e0770642ace75adfac0524230e09ef7b407635 +size 1280044 diff --git a/scripts/testv/stvFOA32c_cut_16.0.wav b/scripts/testv/stvFOA32c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..213a894796abeabd1494cbf71ebd7329e81e5042 --- /dev/null +++ b/scripts/testv/stvFOA32c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e55b8064e43221eff40393b903c973aae937244874f677f4a9358c8cb16caba +size 1280044 diff --git a/scripts/testv/stvFOA48c_cut.wav b/scripts/testv/stvFOA48c_cut.wav new file mode 100644 index 0000000000000000000000000000000000000000..7f3c6231ec70202b3d35aba5d24471ac221ae324 --- /dev/null +++ b/scripts/testv/stvFOA48c_cut.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d86c4f8fcd8de2395cbe83a9d7846c107bf4a34c4878c6731827ff2acf6f9a7 +size 1920044 diff --git a/scripts/testv/stvFOA48c_cut_.004.wav b/scripts/testv/stvFOA48c_cut_.004.wav new file mode 100644 index 0000000000000000000000000000000000000000..f6bbf0f1ff06cdd0aebc425da8f9bf1935846047 --- /dev/null +++ b/scripts/testv/stvFOA48c_cut_.004.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5e40af6a3133a734abebb25071de55cec175d824b381ae92948489ef2099cc5 +size 1920044 diff --git a/scripts/testv/stvFOA48c_cut_16.0.wav b/scripts/testv/stvFOA48c_cut_16.0.wav new file mode 100644 index 0000000000000000000000000000000000000000..30a9b21f2c442aa75b983d322e111d6f05e8186c --- /dev/null +++ b/scripts/testv/stvFOA48c_cut_16.0.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07ba1c3ebfe3c427fab6efc0c9f58b3bfe3a744e5cb394653ac92457d6b46250 +size 1920044 diff --git a/tests/cmp_pcm.py b/tests/cmp_pcm.py index 709c8ddb8dfc5ac4307e82452122f6b96d3183b2..d958327ccda7ddd9da99f0737133a3bcd9d8b4b2 100755 --- a/tests/cmp_pcm.py +++ b/tests/cmp_pcm.py @@ -20,7 +20,8 @@ def cmp_pcm(file1, file2, out_config, fs, get_mld=False, mld_lim=0, abs_tol=0) - print("=====================") out_config = "MONO" if out_config == "" else out_config - if out_config.upper() not in pyivastest.constants.OC_TO_NCHANNELS: + # out_config may be a string or a Path. Wrap in str() to avoid error in case it is a Path. + if str(out_config).upper() not in pyivastest.constants.OC_TO_NCHANNELS: out_config_in_file_names = os.path.splitext(os.path.basename(out_config))[0] nchannels = ( pyivastest.IvasScriptsCommon.IvasScript.get_n_channels_from_ls_layout( @@ -43,7 +44,11 @@ def cmp_pcm(file1, file2, out_config, fs, get_mld=False, mld_lim=0, abs_tol=0) - f"file size in samples: file 1 = {s1.shape[0]},", f"file 2 = {s2.shape[0]}", ) - return 1, "FAIL: File lengths differ" + reason = "FAIL: File lengths differ. MAXIMUM ABS DIFF: None" + if get_mld: + reason += " - MLD: None" + + return 1, reason cmp_result = pyaudio3dtools.audioarray.compare( s1, s2, fs, per_frame=False, get_mld=get_mld diff --git a/tests/codec_be_on_mr_nonselection/__init__.py b/tests/codec_be_on_mr_nonselection/__init__.py index aba85788e77b1889a019b49dc761a76b04fa8ac4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/tests/codec_be_on_mr_nonselection/__init__.py +++ b/tests/codec_be_on_mr_nonselection/__init__.py @@ -1,2 +0,0 @@ -MLD_PATTERN = r"MLD: ([\d\.]*)" -MAX_DIFF_PATTERN = r"MAXIMUM ABS DIFF: (\d*)" diff --git a/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py b/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py index 9a8d8b35d50ffd698012e89016a1905a9df84817..34fa40e278234b784a8c8e9fdf63aac78cdbb3b3 100644 --- a/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py +++ b/tests/codec_be_on_mr_nonselection/test_masa_enc_dec.py @@ -44,7 +44,7 @@ import pytest from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend -from . import MLD_PATTERN, MAX_DIFF_PATTERN +from ..constants import MLD_PATTERN, MAX_DIFF_PATTERN # params # output_mode_list = ['MONO', 'STEREO', '5_1', '7_1', '5_1_2', '5_1_4', '7_1_4', 'FOA', 'HOA2', 'HOA3', 'BINAURAL', 'BINAURAL_ROOM', 'EXT'] diff --git a/tests/codec_be_on_mr_nonselection/test_param_file.py b/tests/codec_be_on_mr_nonselection/test_param_file.py index 12e9208da89f6d57edf4e4cc486ffcdadea4ae5b..5b0f7f696a278ec51462e4d9a7bfec191e413914 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -39,14 +39,12 @@ import re import platform from pathlib import Path from subprocess import run - import pytest from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend -from tests.cut_pcm import cut_samples from tests.testconfig import PARAM_FILE -from . import MLD_PATTERN, MAX_DIFF_PATTERN +from ..constants import MLD_PATTERN, MAX_DIFF_PATTERN VALID_DEC_OUTPUT_CONF = [ "MONO", @@ -65,6 +63,8 @@ VALID_DEC_OUTPUT_CONF = [ "EXT", ] +PARAM_FILE_ID = "stv" if PARAM_FILE.stem == "self_test" else PARAM_FILE.stem.replace("self_test_", "") + param_file_test_dict = {} with open(PARAM_FILE, "r", encoding="UTF-8") as fp: data = fp.read() @@ -127,6 +127,8 @@ def convert_test_string_to_tag(test_string): @pytest.mark.create_ref @pytest.mark.parametrize("test_tag", list(param_file_test_dict.keys())) +# hack to have stv/ltv/evs in the test name +@pytest.mark.parametrize("param_file_id", [PARAM_FILE_ID]) def test_param_file_tests( record_property, decoder_only, @@ -141,6 +143,7 @@ def test_param_file_tests( rootdir, keep_files, test_tag, + param_file_id, get_mld, get_mld_lim, abs_tol, @@ -165,17 +168,6 @@ def test_param_file_tests( sampling_rate = int(fs) bitrate = enc_split.pop() - sba_br_switching_dtx = 0 - if ( - not bitrate.isdigit() - and "-dtx" in enc_split - and "-sba" in enc_split - and Path(testv_file).name.startswith("stv") - ): - sba_br_switching_dtx = 1 - cut_file = pre_proc_input(testv_file, fs) - testv_file = cut_file - # bitrate can be a filename: remove leading "../" if bitrate.startswith("../"): bitrate = bitrate[3:] @@ -202,10 +194,6 @@ def test_param_file_tests( enc_split, update_ref, ) - if sba_br_switching_dtx == 1 and not keep_files: - is_exist = os.path.exists(cut_file) - if is_exist: - os.remove(cut_file) # check for networkSimulator_g192 command line if sim_opts != "": @@ -352,7 +340,12 @@ def test_param_file_tests( max_diff =0 if output_differs: search_result = re.search(MAX_DIFF_PATTERN, reason) - max_diff = search_result.groups(1)[0] + if search_result: + max_diff = search_result.groups(1)[0] + else: + msg = "Error " + MAX_DIFF_PATTERN + " not found" + print(msg) + pytest.fail(msg) record_property("MAXIMUM ABS DIFF", max_diff) metadata_differs = False @@ -446,21 +439,6 @@ def encode( ) -def pre_proc_input(testv_file, fs): - cut_from = "0.0" - cut_len = "5.0" - cut_gain = "0.004" - if "stvFOA" in testv_file: - num_channel = "4" - elif "stv2OA" in testv_file: - num_channel = "9" - elif "stv3OA" in testv_file: - num_channel = "16" - cut_file = testv_file.replace(".wav", num_channel + "chn_" + cut_gain + ".wav") - cut_samples(testv_file, cut_file, num_channel, cut_from, cut_len, cut_gain) - return cut_file - - def simulate( reference_path, dut_base_path, diff --git a/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py b/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py index a11d1d30bf840b5487672f5c5a7a597803092bc6..289d10fae131b4997c437ba9eff3e54bc11515ae 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py +++ b/tests/codec_be_on_mr_nonselection/test_sba_bs_dec_plc.py @@ -40,7 +40,7 @@ import pytest from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend -from . import MLD_PATTERN, MAX_DIFF_PATTERN +from ..constants import MLD_PATTERN, MAX_DIFF_PATTERN # params tag_list = ["stvFOA"] diff --git a/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py b/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py index b7effa986c272f4799583589e2d12262f026c745..2415d9d9a9cae225bcfc03ae6a274624cf874c74 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py +++ b/tests/codec_be_on_mr_nonselection/test_sba_bs_enc.py @@ -42,8 +42,7 @@ from cut_bs import cut_from_start from tests.cmp_pcm import cmp_pcm from tests.conftest import DecoderFrontend, EncoderFrontend -from tests.cut_pcm import cut_samples -from . import MLD_PATTERN, MAX_DIFF_PATTERN +from ..constants import MLD_PATTERN, MAX_DIFF_PATTERN # params @@ -585,16 +584,7 @@ def sba_enc( cut_file = f"{test_vector_path}/{tag_in}_cut{in_extension}" else: cut_file = f"{test_vector_path}/{tag_in}_cut_{cut_gain}{in_extension}" - if not os.path.exists(cut_file): - cut_samples( - input_path, - cut_file, - num_channels, - cut_from, - cut_len, - cut_gain, - sample_rate=sampling_rate + "000", - ) + input_path = cut_file if ref_encoder_frontend: diff --git a/tests/conformance-test/conftest.py b/tests/conformance-test/conftest.py index 5eea228c451ce70344d33e45f0f6466ceef71cfa..1550e6c3fb0047056827573adfac83cddbe9974d 100644 --- a/tests/conformance-test/conftest.py +++ b/tests/conformance-test/conftest.py @@ -54,6 +54,13 @@ def pytest_addoption(parser): type=pathlib.Path, default='./bin/IVAS_rend', ) + parser.addoption( + "--isar_post_renderer_path", + action="store", + help="path to renderer binary ISAR_post_rend(.exe)", + type=pathlib.Path, + default='./bin/ISAR_post_rend', + ) @pytest.fixture(scope="session") @@ -69,3 +76,8 @@ def decoder_path(request) -> str: @pytest.fixture(scope="session") def renderer_path(request) -> str: return str(request.config.option.renderer_path.absolute()) + + +@pytest.fixture(scope="session") +def isar_post_renderer_path(request) -> str: + return str(request.config.option.isar_post_renderer_path.absolute()) diff --git a/tests/conformance-test/test_26252.py b/tests/conformance-test/test_26252.py index d8796b5ae7255810d6f79a25d8cdbb892d0f75c7..872c634b392fb0f462010199679d8c72287e2a17 100644 --- a/tests/conformance-test/test_26252.py +++ b/tests/conformance-test/test_26252.py @@ -59,7 +59,7 @@ def replace_paths(instr, testv_path, ref_path, cut_path): test_dict = {} TEST_DIR = "." -scripts=["Readme_IVAS_enc.txt", "Readme_IVAS_dec.txt", "Readme_IVAS_rend.txt", "Readme_IVAS_JBM_dec.txt"] +scripts=["Readme_IVAS_enc.txt", "Readme_IVAS_dec.txt", "Readme_IVAS_rend.txt", "Readme_IVAS_JBM_dec.txt", "Readme_IVAS_ISAR_dec.txt", "Readme_IVAS_ISAR_post_rend.txt"] for s in scripts: with open(os.path.join(TEST_DIR, s), "r", encoding="UTF-8") as fp: @@ -68,6 +68,7 @@ for s in scripts: dec_opts = "" diff_opts = "" rend_opts = "" + isar_post_rend_opts = "" testv_path = "" ref_path = "" cut_path = "" @@ -86,32 +87,32 @@ for s in scripts: if line.startswith("$CUT_DEC_BIN"): dec_opts = line if line.startswith("$CUT_REND_BIN"): - rend_opts = line + rend_opts = line + if line.startswith("$CUT_ISAR_POST_REND_BIN"): + isar_post_rend_opts = line if line.startswith("$DIFF_BIN"): diff_opts = line tag = s + "--" + diff_opts.split()[2].split('/')[-1] if tag in test_dict: print("non-unique tag found - ignoring new entry") continue - test_dict[tag] = (enc_opts, dec_opts, rend_opts, diff_opts, testv_path, ref_path, cut_path) + test_dict[tag] = (enc_opts, dec_opts, rend_opts, isar_post_rend_opts, diff_opts, testv_path, ref_path, cut_path) tag = "" enc_opts = "" dec_opts = "" rend_opts = "" + isar_post_rend_opts = "" diff_opts = "" for proc in preproc: proc = replace_paths(proc, testv_path, ref_path, cut_path) path_arg = proc.split()[-1] - if "rm" in proc: - if os.path.exists(path_arg): - shutil.rmtree(path_arg, onerror=remove_readonly) # Needed for folder tree removal on Windows. if "mkdir" in proc: Path(path_arg).mkdir(parents=True, exist_ok=True) @pytest.mark.parametrize("test_tag", list(test_dict.keys())) -def test_26252(test_tag, encoder_path, decoder_path, renderer_path): +def test_26252(test_tag, encoder_path, decoder_path, renderer_path, isar_post_renderer_path): - enc_opts, dec_opts, rend_opts, diff_opts, testv_path, ref_path, cut_path = test_dict[test_tag] + enc_opts, dec_opts, rend_opts, isar_post_rend_opts, diff_opts, testv_path, ref_path, cut_path = test_dict[test_tag] if enc_opts: enc_opts = replace_paths(enc_opts, testv_path, ref_path, cut_path) @@ -122,6 +123,9 @@ def test_26252(test_tag, encoder_path, decoder_path, renderer_path): if rend_opts: rend_opts = replace_paths(rend_opts, testv_path, ref_path, cut_path) subprocess.run([renderer_path] + rend_opts.split()[1:], check = True) + if isar_post_rend_opts: + isar_post_rend_opts = replace_paths(isar_post_rend_opts, testv_path, ref_path, cut_path) + subprocess.run([isar_post_renderer_path] + isar_post_rend_opts.split()[1:], check = True) diff_opts = replace_paths(diff_opts, testv_path, ref_path, cut_path) result = True diff --git a/tests/conftest.py b/tests/conftest.py index c975e409c01ed4a2401e146d6946cdaba37bb7ba..cec06c2061b767601e6de4f85e13e9f377a330e5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -128,6 +128,7 @@ def pytest_addoption(parser): parser.addoption( "--param_file", action="store", + type=Path, help="If specified, use given param file in test_param_file.", ) @@ -312,6 +313,7 @@ class EncoderFrontend: pca: Optional[bool] = None, quiet_mode: Optional[bool] = True, add_option_list: Optional[list] = None, + run_dir: Optional[Path] = None, ) -> None: command = [self._path] @@ -347,7 +349,7 @@ class EncoderFrontend: try: result = run( - command, capture_output=True, check=False, timeout=self.timeout + command, capture_output=True, check=False, timeout=self.timeout, cwd=run_dir ) except TimeoutExpired: pytest.fail(f"{self._type} encoder run timed out after {self.timeout}s.") @@ -486,6 +488,7 @@ class DecoderFrontend: quiet_mode: Optional[bool] = True, plc_file: Optional[Path] = None, add_option_list: Optional[list] = None, + run_dir: Optional[Path] = None, ) -> None: command = [self._path] @@ -521,7 +524,7 @@ class DecoderFrontend: try: if not os.path.exists(str(input_bitstream_path) + eid_output_suffix): - result = run(eid_command, check=True) + result = run(eid_command, check=True, cwd=run_dir) except Exception: pytest.fail("eid-xor operation failed!") @@ -545,7 +548,7 @@ class DecoderFrontend: try: result = run( - command, capture_output=True, check=False, timeout=self.timeout + command, capture_output=True, check=False, timeout=self.timeout, cwd=run_dir ) except TimeoutExpired: pytest.fail(f"{self._type} decoder run timed out after {self.timeout}s.") diff --git a/tests/constants.py b/tests/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..453c07dca83b7edb3dcaeadc859cb164bb6945bc --- /dev/null +++ b/tests/constants.py @@ -0,0 +1,3 @@ +# regex patterns for parsing the output from cmp_pcm -> mainly for BASOP ci +MLD_PATTERN = r"MLD: ([\d\.]*)" +MAX_DIFF_PATTERN = r"MAXIMUM ABS DIFF: (\d*)" diff --git a/tests/create_short_testvectors.py b/tests/create_short_testvectors.py index e51f018f451ced981a72fa502103026a3b5543e4..b90771cca18eac9f2ee65c5f7d548f896a41c39e 100755 --- a/tests/create_short_testvectors.py +++ b/tests/create_short_testvectors.py @@ -42,14 +42,15 @@ from cut_pcm import cut_samples HERE = Path(__file__).parent.resolve() TEST_VECTOR_DIR = HERE.joinpath("../scripts/testv").resolve() +SCRIPTS_DIR = HERE.joinpath("../scripts").resolve() -NUM_CHANNELS = "4" # currently only FOA -CUT_FROM = "0.0" +sys.path.append(SCRIPTS_DIR) +from pyaudio3dtools import audiofile +CUT_FROM = "0.0" +GAIN = "1.0" FILE_IDS = [ - "stvFOA", - "stv2OA", - "stv3OA", + "stvST", "stv51MC", "stv71MC", "stv512MC", @@ -58,40 +59,31 @@ FILE_IDS = [ "ISM", "MASA", ] -GAINS = ["1.0", "16.0", ".004"] -def collect_files(file_ids): +def collect_files(): files = [ f.absolute() for f in TEST_VECTOR_DIR.iterdir() if f.suffix == ".wav" - and any([id in f.name for id in file_ids]) + and any([id in f.name for id in FILE_IDS]) and "_cut" not in f.name ] return files -def create_short_testvectors(which="foa", cut_len=5.0): - file_ids = [] - if which == "all": - file_ids = FILE_IDS - elif which == "foa": - file_ids = FILE_IDS[:1] - - for f in collect_files(file_ids): - for g in GAINS: - suffix = "_cut" - if g != "1.0": - suffix += f"_{g}" +def create_short_testvectors(cut_len=5.0): + files = collect_files() - out_file = f.parent.joinpath(f.stem + suffix + f.suffix) - cut_samples(f, out_file, NUM_CHANNELS, CUT_FROM, f"{cut_len}", g) + for f in files: + suffix = "_cut" + out_file = f.parent.joinpath(f.stem + suffix + f.suffix) + num_channels = audiofile.get_wav_file_info(f)["channels"] + cut_samples(f, out_file, num_channels, CUT_FROM, f"{cut_len}", GAIN) if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument("--which", choices=["foa", "all"], default="foa") def positive_float(x: str) -> float: x = float(x) @@ -101,6 +93,5 @@ if __name__ == "__main__": parser.add_argument("--cut_len", type=positive_float, default=5.0) args = parser.parse_args() - which = args.which cut_len = args.cut_len - sys.exit(create_short_testvectors(which=args.which, cut_len=cut_len)) + sys.exit(create_short_testvectors(cut_len=cut_len)) diff --git a/tests/hrtf_binary_loading/constants.py b/tests/hrtf_binary_loading/constants.py index 1524e9bf57edc72a71b434bde9c7245311c000a8..e0facd538c89101994374c0efcc67eb6cce5b1a4 100644 --- a/tests/hrtf_binary_loading/constants.py +++ b/tests/hrtf_binary_loading/constants.py @@ -51,11 +51,18 @@ DECODER_CMD = [str(TESTS_DIR.parent.parent.joinpath("IVAS_dec"))] RENDERER_CMD = [str(TESTS_DIR.parent.parent.joinpath("IVAS_rend"))] HRTF_BINARY_FILE_SAME_AS_ROM = "ivas_binaural_{}kHz.bin" +HRTF_BINARY_FILE_SAME_AS_ROM_FX = "ivas_binaural_fx_{}kHz.bin" HRTF_BINARY_FILE_DIFF_FROM_ROM = "ivas_binaural_51_brir-lc_{}kHz.bin" +HRTF_BINARY_FILE_DIFF_FROM_ROM_FX = "ivas_binaural_51_brir-lc_fx_{}kHz.bin" +# HRTF_FILES = [HRTF_BINARY_FILE_SAME_AS_ROM,HRTF_BINARY_FILE_SAME_AS_ROM_FX, HRTF_BINARY_FILE_DIFF_FROM_ROM, HRTF_BINARY_FILE_DIFF_FROM_ROM_FX] HRTF_FILES = [HRTF_BINARY_FILE_SAME_AS_ROM, HRTF_BINARY_FILE_DIFF_FROM_ROM] +DEFAULT_BIN_FILE_FX_FLAG = 0x1000 HRTF_TAG_SAME_AS_ROM = "hrtf_same_as_rom" +HRTF_TAG_SAME_AS_ROM_FX = "hrtf_same_as_rom_fx" HRTF_TAG_DIFF_FROM_ROM = "hrtf_diff_from_rom" +HRTF_TAG_DIFF_FROM_ROM_FX = "hrtf_diff_from_rom_fx" +# HRTF_TAGS = [HRTF_TAG_SAME_AS_ROM, HRTF_TAG_SAME_AS_ROM_FX, HRTF_TAG_DIFF_FROM_ROM, HRTF_TAG_DIFF_FROM_ROM_FX] HRTF_TAGS = [HRTF_TAG_SAME_AS_ROM, HRTF_TAG_DIFF_FROM_ROM] HRTF_FILE_FOR_TAG = dict(zip(HRTF_TAGS, HRTF_FILES)) @@ -162,6 +169,15 @@ with open( globals()[biace_c[biacid1 : biacid1 + biacid2]] = enumid enumid += 1 +# HRTF_READER_RENDERER_BINAURAL_INVALID = 0 +# HRTF_READER_RENDERER_BINAURAL_FASTCONV = 1 +# HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM = 2 +# HRTF_READER_RENDERER_BINAURAL_PARAMETRIC = 3 +# HRTF_READER_RENDERER_BINAURAL_OBJECTS_TD = 4 +# HRTF_READER_RENDERER_BINAURAL_MIXER_CONV = 5 +# HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM = 6 +# HRTF_READER_RENDERER_BINAURAL_REVERB_ALL = 7 + HRTF_READER_RENDERER_BINAURAL_INVALID = 0 HRTF_READER_RENDERER_BINAURAL_FASTCONV = 1 HRTF_READER_RENDERER_BINAURAL_FASTCONV_ROOM = 2 diff --git a/tests/hrtf_binary_loading/utils.py b/tests/hrtf_binary_loading/utils.py index c1b34c57cd14daf9ba57940c2e7cde5d7c8a2690..1d77e14b033e5a310cfa371978a30ba0fe359e38 100644 --- a/tests/hrtf_binary_loading/utils.py +++ b/tests/hrtf_binary_loading/utils.py @@ -187,6 +187,8 @@ def check_binary_file(hrtf_tag, out_fs): hrtf_header = binary_data[read_bid : read_bid + 16] renderer_type = int.from_bytes(hrtf_header[:4], byteorder="little") + if (renderer_type > DEFAULT_BIN_FILE_FX_FLAG): + renderer_type = renderer_type - DEFAULT_BIN_FILE_FX_FLAG input_configuration = int.from_bytes(hrtf_header[4:8], byteorder="little") sampling_frequency = int.from_bytes(hrtf_header[8:12], byteorder="little") raw_data_size = int.from_bytes(hrtf_header[12:16], byteorder="little") @@ -293,7 +295,7 @@ def compare_rom_vs_binary( hrtf_file = HRTF_FILE_FOR_TAG[hrtf_tag] - xfail = hrtf_file == HRTF_BINARY_FILE_DIFF_FROM_ROM + xfail = (hrtf_file == HRTF_BINARY_FILE_DIFF_FROM_ROM) or (hrtf_file == HRTF_BINARY_FILE_DIFF_FROM_ROM_FX) input_path = TESTV_DIR.joinpath(in_file).with_suffix(".wav") bitstream_path = BITSTREAM_DIR.joinpath(in_file + file_ext) @@ -349,7 +351,7 @@ def compare_renderer_vs_renderer_with_binary_hrir( keep_file=False, ): hrtf_file = HRTF_FILE_FOR_TAG[hrtf_tag] - xfail = hrtf_file == HRTF_BINARY_FILE_DIFF_FROM_ROM + xfail = (hrtf_file == HRTF_BINARY_FILE_DIFF_FROM_ROM) or (hrtf_file == HRTF_BINARY_FILE_DIFF_FROM_ROM_FX) hrtf_file_dir = SCRIPTS_DIR.joinpath( "binauralRenderer_interface/binaural_renderers_hrtf_data" diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 9592103e1d37679993ea6ded5e4b1f619ed81cf6..0e7b13c8ac61f4f761b40c9963befb180673f1ee 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -114,6 +114,14 @@ FORMAT_TO_FILE_SMOKETEST = { "NDP_ISM4": NCHAN_TO_FILE[4], "MASA1": NCHAN_TO_FILE[1], "MASA2": NCHAN_TO_FILE[2], + "OMASA_1_1": NCHAN_TO_FILE[2], + "OMASA_1_2": NCHAN_TO_FILE[3], + "OMASA_1_3": NCHAN_TO_FILE[4], + "OMASA_1_4": NCHAN_TO_FILE[5], + "OMASA_2_1": NCHAN_TO_FILE[3], + "OMASA_2_2": NCHAN_TO_FILE[4], + "OMASA_2_3": NCHAN_TO_FILE[5], + "OMASA_2_4": NCHAN_TO_FILE[6], "OSBA_1_1": NCHAN_TO_FILE[5], "OSBA_2_1": NCHAN_TO_FILE[6], "OSBA_3_1": NCHAN_TO_FILE[7], @@ -149,6 +157,14 @@ FORMAT_TO_FILE_COMPARETEST = { "ISM4": TESTV_DIR.joinpath("stv4ISM48s.wav"), "MASA1": TESTV_DIR.joinpath("stv1MASA1TC48c.wav"), "MASA2": TESTV_DIR.joinpath("stv2MASA2TC48c.wav"), + "OMASA_1_1": TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA1TC48c.wav"), + "OMASA_1_2": TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA1TC48c.wav"), + "OMASA_1_3": TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA1TC48c.wav"), + "OMASA_1_4": TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA1TC48c.wav"), + "OMASA_2_1": TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA2TC48c.wav"), + "OMASA_2_2": TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA2TC48c.wav"), + "OMASA_2_3": TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA2TC48c.wav"), + "OMASA_2_4": TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA2TC48c.wav"), "OSBA_1_1": TESTV_DIR.joinpath("stvOSBA_1ISM_FOA48c.wav"), "OSBA_1_2": TESTV_DIR.joinpath("stvOSBA_1ISM_2OA48c.wav"), "OSBA_1_3": TESTV_DIR.joinpath("stvOSBA_1ISM_3OA48c.wav"), @@ -192,6 +208,50 @@ FORMAT_TO_METADATA_FILES = { ], "MASA1": [str(TESTV_DIR.joinpath("stv1MASA1TC48c.met"))], "MASA2": [str(TESTV_DIR.joinpath("stv2MASA2TC48c.met"))], + "OMASA_1_1": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA1TC48c.met")), + ], + "OMASA_1_2": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA1TC48c.met")), + ], + "OMASA_1_3": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA1TC48c.met")), + ], + "OMASA_1_4": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvISM4.csv")), + str(TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA1TC48c.met")), + ], + "OMASA_2_1": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvOMASA_1ISM_1MASA2TC48c.met")), + ], + "OMASA_2_2": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvOMASA_2ISM_2MASA2TC48c.met")), + ], + "OMASA_2_3": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvOMASA_3ISM_1MASA2TC48c.met")), + ], + "OMASA_2_4": [ + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvISM4.csv")), + str(TESTV_DIR.joinpath("stvOMASA_4ISM_2MASA2TC48c.met")), + ], } diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index 8576dd8d105b04e85822562acf7c7f77dc6cb1ab..3c9b95dbaf66170a9bd4204fc0c25bfc53e83e1a 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -32,7 +32,25 @@ import pytest -from .utils import * +from .constants import ( + OUTPUT_FORMATS, + INPUT_FORMATS_AMBI, + FRAMING_TO_TEST, + EXE_SUFFIX, + OUTPUT_FORMATS_BINAURAL, + HR_TRAJECTORIES_TO_TEST, + HR_TRAJECTORY_DIR, + INPUT_FORMATS_MC, + INPUT_FORMATS_ISM, + FORMAT_TO_METADATA_FILES, + INPUT_FORMATS_MASA, + METADATA_SCENES_TO_TEST_MASA_PREREND, + TEST_VECTOR_DIR, + CUSTOM_LS_TO_TEST, + CUSTOM_LAYOUT_DIR, + METADATA_SCENES_TO_TEST, +) +from .utils import run_renderer, compare_renderer_args, test_info ############################################################################## # Bit-exactness tests @@ -109,6 +127,31 @@ def test_ambisonics_binaural_headrotation( ) +@pytest.mark.create_ref +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL[2:]) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +@pytest.mark.parametrize("frame_size", FRAMING_TO_TEST) +@pytest.mark.parametrize("aeid", ["1", "0"]) +def test_dynamic_acoustic_environment( + record_property, test_info, in_fmt, out_fmt, frame_size, get_mld, get_mld_lim, aeid +): + rend_config_path = TEST_VECTOR_DIR.joinpath(f"rend_config_combined.cfg") + rend_config_path.with_stem(f"rend_config") + + run_renderer( + record_property, + test_info, + in_fmt, + out_fmt, + binary_suffix=EXE_SUFFIX, + frame_size=frame_size, + get_mld=get_mld, + mld_lim=get_mld_lim, + config_file=rend_config_path, + aeid=aeid, + ) + + """ Multichannel """ @@ -354,8 +397,8 @@ def test_masa_prerend(record_property, test_info, in_fmt, get_mld, get_mld_lim): "MASA2", metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), binary_suffix=EXE_SUFFIX, - get_mld=get_mld, - mld_lim=get_mld_lim, + get_mld=get_mld, + mld_lim=get_mld_lim, ) @@ -393,8 +436,8 @@ def test_custom_ls_output( in_fmt, CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), binary_suffix=EXE_SUFFIX, - get_mld=get_mld, - mld_lim=get_mld_lim, + get_mld=get_mld, + mld_lim=get_mld_lim, ) @@ -410,8 +453,8 @@ def test_custom_ls_input_output( CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), binary_suffix=EXE_SUFFIX, - get_mld=get_mld, - mld_lim=get_mld_lim, + get_mld=get_mld, + mld_lim=get_mld_lim, ) @@ -502,8 +545,8 @@ def test_non_diegetic_pan_static( out_fmt, non_diegetic_pan=non_diegetic_pan, binary_suffix=EXE_SUFFIX, - get_mld=get_mld, - mld_lim=get_mld_lim, + get_mld=get_mld, + mld_lim=get_mld_lim, ) @@ -521,8 +564,8 @@ def test_non_diegetic_pan_ism_static( out_fmt, non_diegetic_pan=non_diegetic_pan, binary_suffix=EXE_SUFFIX, - get_mld=get_mld, - mld_lim=get_mld_lim, + get_mld=get_mld, + mld_lim=get_mld_lim, ) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index a538df7ee83c6a771fbf992e0aad18c2ef0bdfc4..9bd2b8f4b77f04a89ef89ca8416de2c840815c5d 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -39,12 +39,23 @@ from typing import Dict, Optional import numpy as np import pytest +import re from .compare_audio import compare_audio_arrays -from .constants import * +from .constants import ( + SCRIPTS_DIR, + OUTPUT_PATH_REF, + OUTPUT_PATH_CUT, + FORMAT_TO_FILE_COMPARETEST, + FORMAT_TO_FILE_SMOKETEST, + RENDERER_CMD, + BIN_SUFFIX_MERGETARGET, +) sys.path.append(SCRIPTS_DIR) from pyaudio3dtools.audiofile import readfile +from ..cmp_pcm import cmp_pcm +from ..constants import MLD_PATTERN, MAX_DIFF_PATTERN # fixture returns test information, enabling per-testcase SNR @@ -62,6 +73,41 @@ def run_cmd(cmd, env=None): f"Command returned non-zero exit status ({e.returncode}): {' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}" ) +def run_isar_ext_rend_cmd(cmd, env=None): + logging.info(f"\nRunning ISAR EXT REND command\n{' '.join(cmd)}\n") + try: + sp.run(cmd, check=True, capture_output=True, text=True, env=env) + 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 run_ivas_isar_enc_cmd(cmd, env=None): + logging.info(f"\nRunning IVAS ISAR encoder command\n{' '.join(cmd)}\n") + try: + sp.run(cmd, check=True, capture_output=True, text=True, env=env) + 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 run_ivas_isar_dec_cmd(cmd, env=None): + logging.info(f"\nDUT decoder command:\n\t{' '.join(cmd)}\n") + try: + sp.run(cmd, check=True, capture_output=True, text=True, env=env) + 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 run_isar_post_rend_cmd(cmd, env=None): + logging.info(f"\nRunning ISAR post renderer command\n{' '.join(cmd)}\n") + try: + sp.run(cmd, check=True, capture_output=True, text=True, env=env) + 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, @@ -70,7 +116,7 @@ def check_BE( cut: np.ndarray, cut_fs: int, xfail: bool = False, - atol: int = 2 + atol: int = 2, ): if ref is None or np.array_equal(ref, np.zeros_like(ref)): pytest.fail("REF signal does not exist or is zero!") @@ -117,6 +163,8 @@ def run_renderer( hrtf_file: Optional[str] = None, get_mld=False, mld_lim=0, + get_mld_lim=0, + aeid: Optional[str] = None, ) -> str: # prepare arguments and filepaths if trj_file is not None: @@ -149,6 +197,11 @@ def run_renderer( else: framing_name = "" + if aeid is not None: + aeid_name = f"_{aeid}" + else: + aeid_name = "" + if not isinstance(out_fmt, str): out_name = f"{out_fmt.stem}" else: @@ -180,7 +233,7 @@ def run_renderer( in_file = FORMAT_TO_FILE[in_fmt] in_name = in_fmt - out_file_stem = f"{in_name}_to_{out_name}{trj_name}{non_diegetic_pan}{refrot_name}{refvec_name}{refveclev_name}{config_name}{framing_name}{hrtf_file_name}{name_extension}.wav" + out_file_stem = f"{in_name}_to_{out_name}{trj_name}{non_diegetic_pan}{refrot_name}{refvec_name}{refveclev_name}{config_name}{framing_name}{hrtf_file_name}{name_extension}{aeid_name}.wav" out_file = str(output_path_base.joinpath(out_file_stem)) @@ -195,7 +248,7 @@ def run_renderer( cmd[0] += binary_suffix if in_meta_files is not None: - cmd[5:5] = ["-im", *in_meta_files] + cmd.extend(["-im", *in_meta_files]) if trj_file is not None: cmd.extend(["-T", str(trj_file)]) @@ -223,6 +276,9 @@ def run_renderer( if frame_size: cmd.extend(["-fr", str(frame_size.replace("ms", ""))]) + if aeid is not None: + cmd.extend(["-aeid", str(aeid)]) + # Set env variables for UBSAN env = os.environ.copy() if test_info.node.name and "UBSAN_OPTIONS" in env.keys(): @@ -238,6 +294,8 @@ def run_renderer( out_file_ref = str(OUTPUT_PATH_REF.joinpath(out_file_stem)) if get_mld: + # see constants.py + ref_fs = int(cmd[10]) * 1000 output_differs, reason = cmp_pcm( out_file, out_file_ref, @@ -247,9 +305,16 @@ def run_renderer( mld_lim=get_mld_lim, ) mld = 0 - if "MLD" in reason: - mld = float(reason.split(":")[1].split()[0]) - record_property("MLD", mld) + if get_mld: + mld = re.search(MLD_PATTERN, reason).groups(1)[0] + record_property("MLD", mld) + + max_diff = 0 + if output_differs: + search_result = re.search(MAX_DIFF_PATTERN, reason) + max_diff = search_result.groups(1)[0] + record_property("MAXIMUM ABS DIFF", max_diff) + if output_differs: pytest.fail(f"Output differs: ({reason})") else: diff --git a/tests/scale_pcm.py b/tests/scale_pcm.py index 356cdd90e12b95e818bf0f2fa58600fe48d96efc..9aef914da1db574c84c54c0dc7f7d7097691f0ec 100755 --- a/tests/scale_pcm.py +++ b/tests/scale_pcm.py @@ -1,33 +1,33 @@ #!/usr/bin/env python3 -import argparse import os -import pathlib import sys +import argparse +import pathlib THIS_PATH = os.path.join(os.getcwd(), __file__) sys.path.append(os.path.join(os.path.dirname(THIS_PATH), "../scripts")) -import concurrent.futures - import pyaudio3dtools +import pyivastest +import numpy as np +import concurrent.futures def scale_folder(folder, factor): + files = list(folder.glob("*.wav")) with concurrent.futures.ThreadPoolExecutor() as executor: executor.map(scale_file, files, files, [factor] * len(files)) - -def scale_file(file1, file2, factor=1.0) -> None: +def scale_file(file1, file2, factor = 1.0) -> None: """ Scale file1 to file2 """ s1, fs = pyaudio3dtools.audiofile.readfile(file1) - s2 = s1 * factor + s2 = s1 * factor; pyaudio3dtools.audiofile.writefile(file2, s2, fs) - if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("folder", type=pathlib.Path) diff --git a/tests/split_rendering/README.md b/tests/split_rendering/README.md index 0ff6b8dd0ce8dd8a4b51da050c3585bbd389fa9c..b63214c13beb48b437dde08ca0ca9fd57b65f4dc 100644 --- a/tests/split_rendering/README.md +++ b/tests/split_rendering/README.md @@ -1,5 +1,5 @@