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 2576bc96aed7064958bf01c0c7ec8ced54a8e8f2..1dabff9278a8d080b52bbbc5aa12c14adb9b4f0f 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_ALL" 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,6 +168,12 @@ stages: - git pull - cd - +.update-ltv-repo-win: &update-ltv-repo-win + - Push-Location + - cd $LTV_DIR_WIN + - git pull + - Pop-Location + .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 @@ -189,6 +196,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 @@ -431,7 +443,7 @@ build-codec-instrumented-linux: extends: - .build-job-linux - .rules-basis - timeout: "7 minutes" + timeout: "10 minutes" script: - *print-common-info - *activate-Werror-linux @@ -502,7 +514,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 # --------------------------------------------------------------- @@ -525,11 +536,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: @@ -538,8 +548,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" @@ -592,8 +601,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 @@ -800,6 +807,18 @@ 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: + - *enable-split-rendering + - 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: @@ -898,8 +917,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 @@ -953,8 +970,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 @@ -1161,7 +1176,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: @@ -1172,6 +1187,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 @@ -1278,8 +1315,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 @@ -1348,7 +1383,7 @@ 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 @@ -1356,22 +1391,20 @@ ivas-conformance: exit_codes: - 123 script: - - *print-common-info-windows - - 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 + - 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 @@ -1380,10 +1413,13 @@ ivas-conformance: - 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 -force -ErrorAction Ignore scripts/testv/* testvec/testv - cp -r -force -ErrorAction Ignore scripts/ls_layouts testvec @@ -1393,14 +1429,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 @@ -1419,6 +1467,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 @@ -1427,7 +1477,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: @@ -1441,14 +1491,13 @@ ivas-conformance-linux: - cp IVAS_rend IVAS_rend_ref # 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 @@ -1457,6 +1506,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 @@ -1466,32 +1516,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 @@ -1578,7 +1661,7 @@ ltv-msan: - .sanitizer-selftest-ltv rules: - if: $SANITIZER_SCHEDULE_E - timeout: 2 hour + timeout: 3 hour tags: - ivas-linux-fast before_script: @@ -1594,10 +1677,10 @@ ltv-asan: rules: - if: $SANITIZER_SCHEDULE_E when: delayed - start_in: 2 hours + start_in: 3 hours tags: - ivas-linux-fast - timeout: 2 hour + timeout: 3 hour before_script: - CLANG_NUM=2 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS @@ -1611,10 +1694,10 @@ ltv-usan: rules: - if: $SANITIZER_SCHEDULE_E when: delayed - start_in: 3 hours + start_in: 6 hours tags: - ivas-linux-fast - timeout: 2 hour + timeout: 3 hour before_script: - CLANG_NUM=3 - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS @@ -1664,7 +1747,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 @@ -1686,7 +1769,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 @@ -1697,7 +1780,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 @@ -1708,7 +1791,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 @@ -1719,7 +1802,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 @@ -1730,7 +1813,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 @@ -1741,7 +1824,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 @@ -1752,7 +1835,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 @@ -1763,7 +1846,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 @@ -1774,7 +1857,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 @@ -1785,7 +1868,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 --- @@ -1800,7 +1883,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 @@ -1810,7 +1893,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 @@ -1820,7 +1903,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 @@ -1830,7 +1913,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 @@ -1840,7 +1923,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 @@ -1850,7 +1933,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 @@ -1860,7 +1943,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 @@ -1870,7 +1953,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 @@ -1880,7 +1963,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 @@ -1890,7 +1973,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 @@ -1900,7 +1983,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 @@ -1910,7 +1993,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 @@ -1920,7 +2003,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 @@ -1931,7 +2014,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 --- @@ -1947,7 +2030,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 @@ -1957,7 +2040,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 @@ -1967,7 +2050,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 @@ -1978,7 +2061,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 @@ -1989,7 +2072,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 --- @@ -2004,7 +2087,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 @@ -2014,7 +2097,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 @@ -2024,7 +2107,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 @@ -2034,7 +2117,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 @@ -2044,7 +2127,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 @@ -2054,7 +2137,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 @@ -2064,7 +2147,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 @@ -2074,7 +2157,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 @@ -2084,7 +2167,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 @@ -2094,7 +2177,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 @@ -2104,7 +2187,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 @@ -2114,7 +2197,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 @@ -2124,7 +2207,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 @@ -2134,7 +2217,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 @@ -2144,7 +2227,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 @@ -2165,7 +2249,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 @@ -2206,7 +2289,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 b96aa88d11c1320fd8172baaffbc445780e767e1..17799f0db0009b84f104c03e67137b2afe27edb3 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) -if(INCLUDE_SPLIT) - target_include_directories(lib_com PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug lib_isar) +target_include_directories(lib_com PRIVATE lib_lc3plus) file(GLOB libDebugSrcs "lib_debug/*.c") file(GLOB libDebugHeaders "lib_debug/*.h") add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders}) target_link_libraries(lib_debug lib_com) -target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend) +target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend lib_isar) file(GLOB libEncSrcs "lib_enc/*.c") file(GLOB libEncHeaders "lib_enc/*.h") add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) target_link_libraries(lib_enc lib_com lib_debug) -target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend) -if(INCLUDE_SPLIT) - target_include_directories(lib_enc PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend lib_isar) +target_include_directories(lib_enc PRIVATE lib_lc3plus) -if(INCLUDE_SPLIT) - file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") - file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") - add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) - target_include_directories(lib_lc3plus PUBLIC lib_lc3plus) - target_link_libraries(lib_lc3plus lib_com) # For including options.h, which is needed for instrumentation to work correctly - if(WMOPS) - target_link_libraries(lib_lc3plus lib_debug) - endif() -endif() +file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") +file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") +add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) +target_include_directories(lib_lc3plus PUBLIC lib_lc3plus PRIVATE lib_com lib_debug) file(GLOB libRendSrcs "lib_rend/*.c") file(GLOB libRendHeaders "lib_rend/*.h") -if(NOT INCLUDE_SPLIT) - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitrenderer.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_Pred.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_RMSEnv.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_PerceptualModel.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.c$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.h$") -endif() add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed. -if(INCLUDE_SPLIT) - target_link_libraries(lib_rend lib_lc3plus) -endif() -target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc) +target_link_libraries(lib_rend lib_lc3plus lib_isar) +target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc lib_isar) file(GLOB libDecSrcs "lib_dec/*.c") file(GLOB libDecHeaders "lib_dec/*.h") add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) -target_link_libraries(lib_dec lib_com lib_rend lib_debug) -target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc) +target_link_libraries(lib_dec lib_com lib_rend lib_debug lib_isar) +target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_isar) file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") -if(NOT INCLUDE_SPLIT) - list(FILTER libUtilSrcs EXCLUDE REGEX ".*lib_util\/.*split_rend.*\.c$") -endif() add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug) -if(INCLUDE_SPLIT) - target_include_directories(lib_util PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_util PRIVATE lib_lc3plus lib_isar) -if(INCLUDE_SPLIT) - if(NOT WMOPS) +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) +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 2228349d5e2a45224556afb18545d8a6f65cf2ab..c124382c9c04fb2b561082fae8210a5cebc0a3b1 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -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 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 d11b9087ee8167fc0c476be9c0122e0b5c3c5d7d..223f837a2e1685afeedb952a5137dab7b902b3a6 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -59,7 +59,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -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 ea7ad4789712ec14eb05d5f7a5fd9531268420f6..3c7ea3e597de37d9377fc8ad745a158d37ca713c 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -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 diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index aac96693ceb036bf7249629684ab74d7a6b1d2c6..ba0c4c9b6f94cbc5af1499ac5c1143fc2a28e611 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -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 diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..fceeb731ced2445a5434805d422d30654718782a --- /dev/null +++ b/Workspace_msvc/lib_isar.vcxproj @@ -0,0 +1,200 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_isar + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + + + + + + + + + + + diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj index 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 de8e09d2838c7d3081f06b4f5a9502c347c01a08..27d4a19a693cf86f60b3ce654912c65b4a7cbaa6 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -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 @@ - - - diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 80e744c4f1d2f30dcf056057c8582d1ea550585c..c887ffaa96ec38106a0b0669d27b9c274c42e003 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 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 0d795633f17acc67769f50458857da7bc60275df..9d38acb1da54002fbe27e144bd60d4eba4b0f140 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -90,6 +90,17 @@ static * Local structure for storing cmdln arguments *------------------------------------------------------------------------------------------*/ +#ifdef FIX_1053_REVERB_RECONFIGURATION +typedef struct +{ + uint16_t *pID; + uint16_t *pValidity; + uint16_t count; + uint16_t selected; + uint16_t frameCounter; +} AcousticEnvironmentSequence; +#endif + typedef struct { char *inputBitstreamFilename; @@ -141,7 +152,11 @@ typedef struct uint16_t tsmScale; #endif #endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + AcousticEnvironmentSequence aeSequence; +#else uint16_t acousticEnvironmentId; +#endif int16_t Opt_dpid_on; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; @@ -155,7 +170,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 ); +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #else static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #endif @@ -181,7 +196,8 @@ int main( 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]; + ISAR_SPLIT_REND_BITS_DATA splitRendBits; + uint8_t splitRendBitsBuf[ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; #endif /* Any handles that require cleanup must be declared here and initialized to NULL */ @@ -215,6 +231,10 @@ int main( reset_mem( USE_BYTES ); #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + splitRendBits.bits_buf = splitRendBitsBuf; +#endif + /*------------------------------------------------------------------------------------------* * Parse command-line arguments *------------------------------------------------------------------------------------------*/ @@ -412,7 +432,8 @@ int main( /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB #ifdef SPLIT_REND_WITH_HEAD_ROT - && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM + && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 #endif ) { @@ -432,9 +453,14 @@ int main( *------------------------------------------------------------------------------------------*/ asked_frame_size = arg.renderFramesize; +#ifdef FIX_1053_REVERB_RECONFIGURATION + 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, aeID, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#else 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 ) ) != IVAS_ERR_OK ) - +#endif { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -450,11 +476,11 @@ int main( fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for decoding to EXT!\n" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------------------------* * Configure Split rendering *------------------------------------------------------------------------------------------*/ -#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 ) { @@ -603,7 +629,8 @@ int main( /* 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; @@ -633,32 +660,47 @@ 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 ) ) +#ifdef CONF_DISTATT + 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 +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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 ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#else if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, arg.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#endif { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -668,11 +710,22 @@ int main( } else { +#ifdef FIX_1053_REVERB_RECONFIGURATION + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); +#else fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", arg.acousticEnvironmentId ); +#endif goto cleanup; } renderConfig.roomAcoustics.override = true; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) arg.renderFramesize /* given in number of 5ms subframes */ * 5; +#endif +#endif if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { @@ -831,7 +884,7 @@ int main( else { #ifdef SPLIT_REND_WITH_HEAD_ROT - error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, splitRendBitsBuf, hIvasDec, pcmBuf ); + error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf ); #else error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); #endif @@ -875,6 +928,13 @@ cleanup: free( pcmBuf ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( arg.aeSequence.count > 0 ) + { + free( arg.aeSequence.pID ); + free( arg.aeSequence.pValidity ); + } +#endif #ifdef DEBUG_SBA_AUDIO_DUMP IVAS_DEC_GetSbaDebugParams( hIvasDec, &numOutChannels, &numTransportChannels, &pca_ingest_channels ); @@ -1090,7 +1150,15 @@ static bool parseCmdlIVAS_dec( arg->tsmScaleFileName = NULL; #endif #endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + arg->aeSequence.count = 0; + arg->aeSequence.pID = NULL; + arg->aeSequence.pValidity = NULL; + arg->aeSequence.selected = 0; + arg->aeSequence.frameCounter = 0; +#else arg->acousticEnvironmentId = 65535; +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { arg->directivityPatternId[i] = 65535; @@ -1474,11 +1542,90 @@ static bool parseCmdlIVAS_dec( if ( !is_digits_only( argv[i] ) ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t k; + char *s = argv[i]; + char *token = argv[i]; + + for ( k = 0; s[k]; ) + { + s[k] == ',' ? k++ : *s++; + } + k++; + + if ( k == 0 ) + { + fprintf( stdout, "Error: Invalid acoustic environment sequence specified: %s\n\n", argv[i] ); + usage_dec(); + return false; + } + + if ( NULL == ( arg->aeSequence.pID = malloc( sizeof( uint16_t ) * k ) ) || + NULL == ( arg->aeSequence.pValidity = malloc( sizeof( uint16_t ) * k ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", argv[i] ); + usage_dec(); + return false; + } + + arg->aeSequence.count = k; + + k = 0; + token = strtok( argv[i++], ":" ); + + while ( token != NULL ) + { + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, argv[i] ); + usage_dec(); + return false; + } + arg->aeSequence.pID[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, "," ); + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, argv[i] ); + usage_dec(); + return false; + } + arg->aeSequence.pValidity[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, ":" ); + k++; + } + + if ( k != arg->aeSequence.count ) + { + fprintf( stdout, "Error while parsing acoustic environment sequence: %s\n\n", argv[i] ); + usage_dec(); + return false; + } +#else fprintf( stdout, "Error: Invalid acoustic environment ID specified: %s\n\n", argv[i] ); usage_dec(); return false; +#endif + } +#ifdef FIX_1053_REVERB_RECONFIGURATION + 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; } +#else arg->acousticEnvironmentId = (int16_t) atoi( argv[i++] ); +#endif } else if ( strcmp( argv_to_upper, "-DPID" ) == 0 ) { @@ -1570,6 +1717,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 { @@ -1717,7 +1871,15 @@ 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" ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + fprintf( stdout, "-aeid ID : Acoustic environment ID (number > 0) or\n" ); + fprintf( stdout, " a sequence thereof in the format [ID1:duration1,ID2:duration2...]\n" ); + fprintf( stdout, " without braces and spaces, with ':' character separating ID from duration and ',' separating\n" ); + fprintf( stdout, " ID and duration pairs, where duration is specified in frames\n" ); + fprintf( stdout, " for BINAURAL_ROOM_REVERB output configuration.\n" ); +#else fprintf( stdout, "-aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration\n" ); +#endif 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" ); @@ -1790,7 +1952,7 @@ static ivas_error initOnFirstGoodFrame( } #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { pFullDelayNumSamples[0] = 0; } @@ -1817,11 +1979,18 @@ static ivas_error initOnFirstGoodFrame( } #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { /* Open split rendering metadata writer */ int16_t delayNumSamples_temp[3]; int32_t delayTimeScale_temp; + ISAR_SPLIT_REND_CODEC splitRendCodec; + int16_t splitRendCodecFrameSizeMs; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t splitRendIsarFrameSizeMs; + int16_t lc3plusHighRes; +#endif if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) { @@ -1829,9 +1998,39 @@ static ivas_error initOnFirstGoodFrame( return error; } - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( ( error = IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec, + &splitRendCodec, + &poseCorrection, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + &splitRendIsarFrameSizeMs, +#endif + &splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + return error; + } + + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) ) { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( splitRendWriter, + arg.outputWavFilename, + delayNumSamples_temp[0], + delayTimeScale_temp, + splitRendCodec, + poseCorrection, + splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + splitRendIsarFrameSizeMs, + arg.output_Fs, + lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1839,7 +2038,26 @@ static ivas_error initOnFirstGoodFrame( } else { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( arg.outputMdFilename == NULL ) + { + fprintf( stderr, "\nOutput split rendering metadata file not specified\n" ); + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + if ( ( error = split_rend_writer_open( splitRendWriter, + arg.outputMdFilename, + delayNumSamples_temp[0], + delayTimeScale_temp, + splitRendCodec, + poseCorrection, + splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + splitRendIsarFrameSizeMs, + arg.output_Fs, + lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1847,7 +2065,7 @@ static ivas_error initOnFirstGoodFrame( } } - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 ) { #endif /* Open audio writer and write all previously skipped bad frames now that frame size is known */ @@ -1868,16 +2086,21 @@ static ivas_error initOnFirstGoodFrame( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( *splitRendWriter != NULL ) { - IVAS_SPLIT_REND_BITS_DATA splitRendBitsZero; + ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero; splitRendBitsZero.bits_buf = NULL; splitRendBitsZero.bits_read = 0; splitRendBitsZero.bits_written = 0; splitRendBitsZero.buf_len = 0; - splitRendBitsZero.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - splitRendBitsZero.pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRendBitsZero.codec_frame_size_ms = 0; + splitRendBitsZero.isar_frame_size_ms = 20; +#else splitRendBitsZero.codec_frame_size_ms = 20; +#endif - if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written, -1, IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, splitRendBitsZero.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); return error; @@ -2041,7 +2264,7 @@ static ivas_error decodeG192( RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, #ifdef SPLIT_REND_WITH_HEAD_ROT - uint8_t *splitRendBitsBuf, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, #endif IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -2082,6 +2305,31 @@ static ivas_error decodeG192( SplitFileReadWrite *splitRendWriter = NULL; #endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + 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; + } + } +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { ismWriters[i] = NULL; @@ -2291,6 +2539,38 @@ static ivas_error decodeG192( { if ( needNewFrame ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + 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; + } + } + } +#endif #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING if ( arg.tsmScaleFileEnabled ) @@ -2345,9 +2625,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 ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBitsBuf, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2427,24 +2707,16 @@ static ivas_error decodeG192( 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 ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - IVAS_SPLIT_REND_BITS_DATA splitRendBits; - - if ( ( error = IVAS_DEC_GetSplitRendBits( hIvasDec, &splitRendBits ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError in IVAS_DEC_SplitRendBits: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - - if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written, splitRendBits.codec, splitRendBits.pose_correction, splitRendBits.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits->bits_buf, &splitRendBits->bits_read, &splitRendBits->bits_written ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); goto cleanup; } } - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 ) { #endif if ( delayNumSamples < nOutSamples ) @@ -2738,6 +3010,9 @@ static ivas_error decodeG192( cleanup: +#ifdef FIX_1053_REVERB_RECONFIGURATION + RenderConfigReader_close( &renderConfigReader ); +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT split_rend_reader_writer_close( &splitRendWriter ); #endif diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..4113ea494f59876b042cf7aa3e1a16f588f52adc --- /dev/null +++ b/apps/isar_post_rend.c @@ -0,0 +1,1253 @@ +/****************************************************************************************************** + + (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" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int main( int argc, char **argv ) +{ + (void) argc; + (void) argv; + ISAR_POST_REND_void_func(); + return 0; +} + +#else + +#include +#include +#include +#include "audio_file_reader.h" +#include "audio_file_writer.h" +#include "cmdl_tools.h" +#include "cmdln_parser.h" +#include "render_config_reader.h" +#include "rotation_file_reader.h" +#include "split_render_file_read_write.h" +#include "split_rend_bfi_file_reader.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#define WMC_TOOL_SKIP + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define POST_REND_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) + +#define ISAR_MAX16B_FLT 32767.0f +#define ISAR_MIN16B_FLT ( -32768.0f ) + +#if !defined( DEBUGGING ) && !defined( WMOPS ) +static +#endif + int32_t frame = 0; + +#ifdef _WIN32 +#define SEP_FOLDER '\\' +#else +#define SEP_FOLDER '/' +#endif + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; + int32_t inputChannelIndex; + float gain_dB; +} RendererInput; + +typedef struct +{ + RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; + uint16_t numBinBuses; +} InputConfig; + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; +} OutputConfig; + +typedef struct +{ + char executableName[POST_REND_MAX_CLI_ARG_LENGTH]; + char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + int32_t sampleRate; + InputConfig inConfig; + OutputConfig outConfig; + char inMetadataFilePaths[RENDERER_MAX_ISAR_MD_INPUTS][POST_REND_MAX_CLI_ARG_LENGTH]; + int16_t numInMetadataFiles; + char headRotationFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char splitRendBFIFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + ISAR_POST_REND_COMPLEXITY_LEVEL complexityLevel; + bool delayCompensationEnabled; + bool quietModeEnabled; + bool sceneDescriptionInput; + IVAS_RENDER_FRAMESIZE render_framesize; +} CmdlnArgs; + +typedef enum +{ + CmdLnOptionId_inputFile = 1, + CmdLnOptionId_inputFormat, + CmdLnOptionId_outputFile, + CmdLnOptionId_sampleRate, + CmdLnOptionId_trajFile, + CmdLnOptionId_orientationTracking, + CmdLnOptionId_complexityLevel, + CmdLnOptionId_noDelayCmp, + CmdLnOptionId_quietModeEnabled, + CmdLnOptionId_inputMetadata, + CmdLnOptionId_listFormats, + CmdLnOptionId_SplitRendBFIFile, + CmdLnOptionId_framing, +} CmdLnOptionId; + +static const CmdLnParser_Option cliOptions[] = { + { + .id = CmdLnOptionId_inputFile, + .match = "input_file", + .matchShort = "i", + .description = "Path to the input file (WAV, raw PCM or scene description file)", + }, + { + .id = CmdLnOptionId_inputFormat, + .match = "input_format", + .matchShort = "if", + .description = "Audio format of input file (e.g. BINAURAL_SPLIT_PCM, use -l for a list)", + }, + { + .id = CmdLnOptionId_inputMetadata, + .match = "input_metadata", + .matchShort = "im", + .description = "Space-separated list of path to metadata files for BINAURAL_SPLIT_PCM input mode", + }, + { + .id = CmdLnOptionId_outputFile, + .match = "output_file", + .matchShort = "o", + .description = "Path to the output file", + }, + { + .id = CmdLnOptionId_sampleRate, + .match = "sample_rate", + .matchShort = "fs", + .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs", + }, + { + .id = CmdLnOptionId_trajFile, + .match = "trajectory_file", + .matchShort = "T", + .description = "Head rotation trajectory file for simulation of head tracking", + }, + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, + { + .id = CmdLnOptionId_noDelayCmp, + .match = "no_delay_compensation", + .matchShort = "no_delay_cmp", + .description = "[flag] Turn off delay compensation", + }, + { + .id = CmdLnOptionId_complexityLevel, + .match = "complexity_level", + .matchShort = "level", + .description = "Complexity level, level = (1, 2, 3), will be defined after characterisation.", + }, + { + .id = CmdLnOptionId_quietModeEnabled, + .match = "quiet", + .matchShort = "q", + .description = "[flag] Limit printouts to terminal", + }, + { + .id = CmdLnOptionId_listFormats, + .match = "list", + .matchShort = "l", + .description = "List supported audio formats", + }, + { + .id = CmdLnOptionId_framing, + .match = "framing", + .matchShort = "fr", + .description = "Set Render audio framing.", + }, +}; + + +/*------------------------------------------------------------------------------------------* + * Local function prototypes + *------------------------------------------------------------------------------------------*/ + +static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); + +static void printSupportedAudioConfigs( void ); + +static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); + +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static ISAR_POST_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( + IVAS_REND_AudioBuffer buffer, + const int16_t chBeginIdx, + const int16_t numChannels ) +{ + ISAR_POST_REND_ReadOnlyAudioBuffer subBuffer; + + subBuffer.config = buffer.config; + subBuffer.config.numChannels = numChannels; + subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; + + return subBuffer; +} + + +static int16_t getTotalNumInChannels( + ISAR_POST_REND_HANDLE hIsarPostRend, + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] ) +{ + int16_t totalNumInChannels = 0; + int16_t i, numInputChannels; + ivas_error error; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + if ( splitBinIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + return totalNumInChannels; +} + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static const CmdLnParser_Option *findOptionById( + const int32_t id ) +{ + for ( int32_t i = 0; i < numCliOptions; ++i ) + { + if ( cliOptions[i].id == id ) + { + return &cliOptions[i]; + } + } + + return NULL; +} + +static bool parseInConfig( + const char *inFormatStr, + InputConfig *inConfig, + bool *sceneDescriptionInput ) +{ + char charBuf[FILENAME_MAX]; + + /* Initialize input config struct */ + inConfig->numBinBuses = 0; + + /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ + strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + if ( strcmp( charBuf, "META" ) == 0 ) + { + *sceneDescriptionInput = true; + /* Parsing the file will be done later. At this point the actual file path + * may not be known as command line parameters are still being parsed. */ + return true; + } + + /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */ + IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr ); + switch ( audioConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + inConfig->numBinBuses = 1; + inConfig->binBuses[0].audioConfig = audioConfig; + inConfig->binBuses[0].inputChannelIndex = 0; + inConfig->binBuses[0].gain_dB = 0.0f; + break; + default: + { + /* Default case covers formats that are defined in the AUDIO_CONFIG enum, + * but cannot be used at input, e.g. BINAURAL */ + const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats ); + fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match ); + return false; + } + } + + return true; +} + + +static bool parseRenderFramesize( + char *value, + IVAS_RENDER_FRAMESIZE *render_framesize ) +{ + int32_t tmp; + + *render_framesize = IVAS_RENDER_FRAMESIZE_UNKNOWN; + if ( !is_digits_only( value ) ) + { + return false; + } + tmp = (int32_t) strtol( value, NULL, 0 ); + switch ( (int16_t) tmp ) + { + case 5: + *render_framesize = IVAS_RENDER_FRAMESIZE_5MS; + break; + case 10: + *render_framesize = IVAS_RENDER_FRAMESIZE_10MS; + break; + case 20: + *render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + break; + default: + return false; + } + + return true; +} + + +static IVAS_AUDIO_CONFIG parseAudioConfig( + const char *configString ) +{ + char charBuf[25]; + charBuf[24] = '\0'; + + strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + + if ( strcmp( charBuf, "BINAURAL" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } + return IVAS_AUDIO_CONFIG_INVALID; +} + + +static bool checkRequiredArgs( + CmdlnArgs args ) +{ + const CmdLnParser_Option *tmpOption; + + /* Check required arguments */ + bool missingRequiredArg = false; + if ( isEmptyString( args.inputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_inputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + + const bool singleInputSpecified = ( args.inConfig.numBinBuses != 0 ); + + if ( !args.sceneDescriptionInput && !singleInputSpecified ) + { + /* Neither scene description input nor single-type input was specified on command line */ + tmpOption = findOptionById( CmdLnOptionId_inputFormat ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( isEmptyString( args.outputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_outputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( args.sampleRate == 0 ) + { + tmpOption = findOptionById( CmdLnOptionId_sampleRate ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( missingRequiredArg ) + { + CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions ); + } + + return !missingRequiredArg; +} + +static CmdlnArgs defaultArgs( + const char *executableName ) +{ + CmdlnArgs args; + + strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH ); + clearString( args.inputFilePath ); + clearString( args.outputFilePath ); + args.sampleRate = 0; + + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID; + + for ( int32_t i = 0; i < RENDERER_MAX_ISAR_MD_INPUTS; ++i ) + { + clearString( args.inMetadataFilePaths[i] ); + } + args.numInMetadataFiles = 0; + + clearString( args.headRotationFilePath ); + clearString( args.splitRendBFIFilePath ); + + args.delayCompensationEnabled = true; + args.quietModeEnabled = false; + args.sceneDescriptionInput = false; + + args.render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + + return args; +} + +static void parseOption( + const int32_t optionId, + char **optionValues, + const int16_t numOptionValues, + void *pOutputStruct ) +{ + CmdlnArgs *args = pOutputStruct; + + switch ( optionId ) + { + case CmdLnOptionId_listFormats: + assert( numOptionValues == 0 ); + printSupportedAudioConfigs(); + exit( 0 ); + case CmdLnOptionId_inputFile: + assert( numOptionValues == 1 ); + strncpy( args->inputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_inputFormat: + assert( numOptionValues == 1 ); + if ( !parseInConfig( optionValues[0], &args->inConfig, &args->sceneDescriptionInput ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + break; + case CmdLnOptionId_inputMetadata: + assert( numOptionValues <= RENDERER_MAX_ISAR_MD_INPUTS ); + for ( int16_t i = 0; i < numOptionValues; ++i ) + { + strncpy( args->inMetadataFilePaths[i], optionValues[i], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + } + args->numInMetadataFiles = numOptionValues; + break; + case CmdLnOptionId_outputFile: + assert( numOptionValues == 1 ); + strncpy( args->outputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_sampleRate: + assert( numOptionValues == 1 ); + args->sampleRate = (int32_t) ( strtol( optionValues[0], NULL, 10 ) * 1000 ); + if ( args->sampleRate == 0 ) + { + fprintf( stderr, "Invalid sampling rate specified\n" ); + exit( -1 ); + } + break; + case CmdLnOptionId_trajFile: + assert( numOptionValues == 1 ); + strncpy( args->headRotationFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_complexityLevel: + assert( numOptionValues == 1 ); + args->complexityLevel = (int32_t) ( strtol( optionValues[0], NULL, 10 ) ); + if ( args->complexityLevel < ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel > ISAR_POST_REND_COMPLEXITY_LEVEL_THREE ) + { + fprintf( stdout, "Invalid complexity level specified.\n" ); + exit( -1 ); + } + else if ( args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_TWO ) + { + fprintf( stdout, "Complexity levels 1 and 2 will be defined after characterisation - default to level 3 (full functionality).\n" ); + } + break; + case CmdLnOptionId_noDelayCmp: + assert( numOptionValues == 0 ); + args->delayCompensationEnabled = false; + break; + case CmdLnOptionId_quietModeEnabled: + assert( numOptionValues == 0 ); + args->quietModeEnabled = true; + break; + case CmdLnOptionId_framing: + assert( numOptionValues == 1 ); + if ( !parseRenderFramesize( optionValues[0], &args->render_framesize ) ) + { + fprintf( stderr, "Unknown or invalid option for frame size: %s\n", optionValues[0] ); + exit( -1 ); + } + + break; + default: + assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); + break; + } + + return; +} + +static CmdlnArgs parseCmdlnArgs( + const int argc, + char **argv ) +{ + CmdlnArgs args = defaultArgs( argv[0] ); + + if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + if ( !checkRequiredArgs( args ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + return args; +} + + +static void printSupportedAudioConfigs( void ) +{ + uint16_t i; + const char *supportedFormats[] = { + "BINAURAL (output only)", + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CODED", + }; + + fprintf( stdout, "Supported audio formats:\n" ); + for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ ) + { + fprintf( stdout, "%s\n", supportedFormats[i] ); + } + + return; +} + +/*--------------------------------------------------------------------------* + * convertInputBuffer() + * + * Convert input buffer from WAV/PCM file (int16_t, interleaved) to a format + * accepted by the renderer (float, packed) + *--------------------------------------------------------------------------*/ + +static void convertInputBuffer( + const int16_t *intBuffer, + const int16_t numIntSamplesPerChannel, + const int16_t numFloatSamplesPerChannel, + const int16_t numChannels, + float *floatBuffer ) +{ + int16_t chnl, smpl, i; + + i = 0; + + for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + if ( i < numIntSamplesPerChannel ) + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + } + else + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + } + + ++i; + } + } + + return; +} + +/*--------------------------------------------------------------------------* + * convertOutputBuffer() + * + * Convert output buffer from the renderer (float, packed) to a format ready + * for writing to a WAV/PCM file (int16_t, interleaved) + *--------------------------------------------------------------------------*/ + +static void convertOutputBuffer( + const float *floatBuffer, + const int16_t numSamplesPerChannel, + const int16_t numChannels, + int16_t *intBuffer ) +{ + int16_t chnl, smpl, i; + float temp; + + i = 0; + + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; + temp = (float) floor( temp + 0.5f ); + if ( temp > ISAR_MAX16B_FLT ) + { + temp = ISAR_MAX16B_FLT; + } + else if ( temp < ISAR_MIN16B_FLT ) + { + temp = ISAR_MIN16B_FLT; + } + intBuffer[i] = (int16_t) temp; + + ++i; + } + } + + return; +} + +/*------------------------------------------------------------------------------------------* + * main() + * + * Main ISAR post renderer function for command-line interface + *------------------------------------------------------------------------------------------*/ + +int main( + int argc, + char **argv ) +{ + ISAR_POST_REND_HANDLE hIsarPostRend; + RotFileReader *headRotReader = NULL; + RotFileReader *externalOrientationFileReader = NULL; + SplitRendBFIFileReader *splitRendBFIReader = NULL; + AudioFileReader *audioReader = NULL; + AudioFileWriter *audioWriter; + int32_t inBufferSize; + int32_t outBufferSize; + int32_t bitsBufferSize; + int16_t *inpInt16Buffer; + float *inFloatBuffer; + int16_t *outInt16Buffer; + float *outFloatBuffer; + uint8_t *bitsBufferData = NULL; + IVAS_REND_AudioBuffer inBuffer; + IVAS_REND_AudioBuffer outBuffer; + ISAR_POST_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + char audioFilePath[FILENAME_MAX]; + int16_t numSamplesRead; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig = 0; + int16_t zeroPad = 0; + int16_t zeroPadToWrite = 0; + int32_t delayTimeScale = 0; + int16_t i, numChannels; + ivas_error error = IVAS_ERR_OK; + bool splitBinNeedsNewFrame = true; + +#ifdef WMOPS + reset_wmops(); + reset_mem( USE_BYTES ); +#endif + + hSplitRendFileReadWrite = NULL; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plusHighRes = 0; +#else + bitsBuffer.config.codec_frame_size_ms = 20; +#endif + + + CmdlnArgs args = parseCmdlnArgs( argc, argv ); + + convert_backslash( args.inputFilePath ); + convert_backslash( args.outputFilePath ); + convert_backslash( args.headRotationFilePath ); + + if ( !isEmptyString( args.headRotationFilePath ) ) + { + if ( RotationFileReader_open( args.headRotationFilePath, &headRotReader ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", args.headRotationFilePath ); + exit( -1 ); + } + } + + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t inFileSampleRate = 0; +#endif + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); + hSplitRendFileReadWrite = NULL; + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inMetadataFilePaths[0], + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes +#endif + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); + exit( -1 ); + } + + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } + } + + /*if split renderer is running in post renderer mode*/ + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inputFilePath, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes +#endif + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); + exit( -1 ); + } + audioReader = NULL; + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t inFileSampleRate = 0; +#endif + if ( audioReader != NULL ) + { + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + } + else +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( hSplitRendFileReadWrite == NULL ) +#endif + { + inFileSampleRate = args.sampleRate; + } + + switch ( error ) + { + case IVAS_ERR_OK: + /* If sampling rate not given on command line, use the one from SR file */ + if ( args.sampleRate == 0 ) + { + args.sampleRate = inFileSampleRate; + } + /* else if sampling rate given on command line, compare with wav file */ + else if ( inFileSampleRate != args.sampleRate ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath ); + exit( -1 ); + } + break; + case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */ + if ( args.sampleRate == 0 ) + { + fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" ); + exit( -1 ); + } + break; + default: + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t inFileNumChannels = 0; + if ( audioReader != NULL ) + { + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_BINAURAL; + if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0.0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + /* === Configure === */ + if ( ( error = ISAR_POST_REND_InitConfig( hIsarPostRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Renderer Config Init: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( args.inConfig.numBinBuses > 0 ) + { + if ( ( error = ISAR_REND_SetSplitRendBitstreamHeader( hIsarPostRend, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + bitsBuffer.config.lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in getting split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + splitBinIds[i] = 0u; + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = ISAR_POST_REND_AddInput( hIsarPostRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + const int16_t totalNumInChannels = getTotalNumInChannels( hIsarPostRend, splitBinIds ); + + if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) + { + fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); + exit( -1 ); + } + + int16_t numOutChannels = 2; + + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } + + inBufferSize = frameSize_smpls * totalNumInChannels; + outBufferSize = frameSize_smpls * numOutChannels; + inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); + + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); + + inBuffer.config.is_cldfb = 0; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; + inBuffer.data = inFloatBuffer; + + outBuffer.config.is_cldfb = 0; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data = outFloatBuffer; + + memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); + + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; + + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the ISAR post renderer ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n\n-- Start the ISAR post renderer (quiet mode) --\n\n" ); + } + + while ( 1 ) + { + int16_t num_in_channels; + num_in_channels = inBuffer.config.numChannels; + + numSamplesRead = 0; + if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) + { + ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten ); + if ( error_tmp != IVAS_ERR_OK ) + { + if ( error_tmp == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + exit( -1 ); + } + } + } + + if ( audioReader != NULL ) + { + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } + } + + if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + { + /* end of input data */ + break; + } + + /* Convert from int to float and from interleaved to packed */ + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); + + int16_t num_subframes, sf_idx; + num_subframes = (int16_t) args.render_framesize; + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) + { + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + IVAS_QUATERNION headRot; + IVAS_VECTOR3 Pos; + + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetHeadRotation( hIsarPostRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + else + { + fprintf( stderr, "Head Rotation should be enabled in post renderer\n" ); + exit( -1 ); + } + + /* Read from split renderer bfi file if specified */ + if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) + { + int16_t bfi; + if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in ISAR_POST_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( numSamplesRead > 0 ) + { + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + ISAR_POST_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = ISAR_POST_REND_FeedInputAudio( hIsarPostRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + if ( splitBinNeedsNewFrame ) + { + if ( ( error = ISAR_POST_REND_FeedSplitBinauralBitstream( hIsarPostRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + + if ( ( error = ISAR_POST_REND_GetSplitBinauralSamples( hIsarPostRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t num_out_channels; + num_out_channels = outBuffer.config.numChannels; + + /* Convert from float to int and from packed to interleaved. + * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ + convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); + + if ( delayNumSamples == -1 ) + { + if ( args.delayCompensationEnabled ) + { + if ( ISAR_POST_REND_GetDelay( hIsarPostRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( hSplitRendFileReadWrite != NULL ) + { + uint32_t pre_rend_delay_ns; + split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns ); + delayNumSamples += (int16_t) roundf( (float) pre_rend_delay_ns * delayTimeScale / 1000000000.f ); + } + + delayNumSamples_orig = delayNumSamples; + } + else + { + delayNumSamples = 0; + } + zeroPad = delayNumSamples; + } + + if ( audioWriter != NULL ) + { + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } + } + + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + + frame++; + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); + } + +#ifdef WMOPS + update_mem(); + update_wmops(); +#endif + } + + /* add zeros at the end to have equal length of synthesized signals */ + if ( audioWriter != NULL ) + { + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + zeroPadToWrite = 0; + } + + if ( !args.quietModeEnabled && args.delayCompensationEnabled ) + { + fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); + } + + fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame ); + +#ifdef DEBUGGING + int32_t cnt_frames_limited, noClipping; + if ( ( cnt_frames_limited = ISAR_POST_REND_GetCntFramesLimited( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited ); + } + if ( ( noClipping = ISAR_POST_REND_GetNoCLipping( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping ); + } +#endif + + /* === Close === */ + free( inpInt16Buffer ); + free( inFloatBuffer ); + free( outInt16Buffer ); + free( outFloatBuffer ); + + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } + + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); + + AudioFileReader_close( &audioReader ); + AudioFileWriter_close( &audioWriter ); + RotationFileReader_close( &headRotReader ); + RotationFileReader_close( &externalOrientationFileReader ); + + ISAR_POST_REND_Close( &hIsarPostRend ); + +#ifdef DEBUGGING + dbgclose(); +#endif +#ifdef WMOPS + print_wmops(); + print_mem( NULL ); +#endif + + return 0; +} + + +#undef WMC_TOOL_SKIP + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/apps/renderer.c b/apps/renderer.c index 8a9e0b48f84f0745af9cdf84ecc08a362669c8fc..f8c53320d1ca65ed22823cf907f90b58445c0642 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -66,10 +66,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 +134,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 +142,17 @@ typedef struct IVAS_CUSTOM_LS_DATA outSetupCustom; } OutputConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION +typedef struct +{ + uint16_t *pID; + uint16_t *pValidity; + uint16_t count; + uint16_t selected; + uint16_t frameCounter; +} AcousticEnvironmentSequence; +#endif + typedef struct { char executableName[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -189,7 +192,11 @@ typedef struct float syncMdDelay; IVAS_RENDER_FRAMESIZE render_framesize; uint16_t directivityPatternId[RENDERER_MAX_ISM_INPUTS]; +#ifdef FIX_1053_REVERB_RECONFIGURATION + AcousticEnvironmentSequence aeSequence; +#else uint16_t acousticEnvironmentId; +#endif } CmdlnArgs; typedef enum @@ -322,10 +329,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 +399,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_acousticEnvironmentId, .match = "acoustic_environment_id", .matchShort = "aeid", +#ifdef FIX_1053_REVERB_RECONFIGURATION + .description = "Acoustic environment ID( number > 0 ) or a sequence thereof in the format [ID1:duration1,ID2:duration2...] without braces and spaces, with ':' character separating ID from duration and ',' separating ID and duration pairs, where duration is specified in frames for BINAURAL_ROOM_REVERB output configuration.", +#else .description = "Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output configuration", +#endif }, }; @@ -478,13 +491,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 +568,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 +576,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 +623,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; } @@ -671,12 +638,12 @@ 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; @@ -690,21 +657,6 @@ static int16_t get_cldfb_in_flag( return cldfb_in_flag; } - -static int16_t is_split_post_rend_mode( - CmdlnArgs *args ) -{ - int16_t flag; - - flag = 0; - if ( args->inConfig.numBinBuses > 0 && ( args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - flag = 1; - } - - return flag; -} - static int16_t is_split_pre_rend_mode( CmdlnArgs *args ) { @@ -784,8 +736,10 @@ int main( int16_t zeroPadToWrite = 0; int32_t delayTimeScale = 0; int16_t i, numChannels; +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t aeID; +#endif ivas_error error = IVAS_ERR_OK; - bool splitBinNeedsNewFrame = true; #ifdef WMOPS reset_wmops(); @@ -802,6 +756,19 @@ int main( hSplitRendFileReadWrite = NULL; CLDFBframeSize_smpls = 0; cldfb_in_flag = 0; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plus_highres = 0; +#else + bitsBuffer.config.codec_frame_size_ms = 20; +#endif #endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { @@ -894,11 +861,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 +882,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 +918,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 ) @@ -1160,7 +1087,12 @@ int main( if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + aeID = args.aeSequence.count > 0 ? args.aeSequence.pID[0] : 65535; + if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, aeID, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#else if ( ( error = RenderConfigReader_getAcousticEnvironment( renderConfigReader, args.acousticEnvironmentId, &renderConfig.roomAcoustics ) ) == IVAS_ERR_OK ) +#endif { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { @@ -1170,12 +1102,24 @@ int main( } else { +#ifdef FIX_1053_REVERB_RECONFIGURATION + fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", aeID ); +#else fprintf( stderr, "Failed to get acoustic environment with ID: %d\n\n", args.acousticEnvironmentId ); +#endif exit( -1 ); } renderConfig.roomAcoustics.override = 1; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) args.render_framesize /* given in number of 5ms subframes */ * 5; +#endif +#endif + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { #ifdef SPLIT_REND_WITH_HEAD_ROT @@ -1187,11 +1131,8 @@ int main( } #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 ); - } + CLDFBframeSize_smpls = frameSize_smpls * 2; + cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); #endif } @@ -1254,9 +1195,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 +1212,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 +1329,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 +1344,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 ) { @@ -1468,13 +1379,37 @@ int main( if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { + + IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms +#endif + ); + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, + args.outputFilePath, + delayNumSamples_temp, + delayTimeScale_temp, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + args.sampleRate, + bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); exit( -1 ); @@ -1485,13 +1420,37 @@ int main( { if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { + + IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms +#endif + ); + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, + args.outMetadataFilePath, + delayNumSamples_temp, + delayTimeScale_temp, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + args.sampleRate, + bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); exit( -1 ); @@ -1539,7 +1498,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,9 +1520,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 ) ); @@ -1601,43 +1557,50 @@ 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 ) +#ifdef FIX_1053_REVERB_RECONFIGURATION + 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 ) + IVAS_RENDER_CONFIG_DATA renderConfig; + + 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 configuratoin 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; } } } +#endif - 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; @@ -1726,25 +1689,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,46 +1829,8 @@ 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 ) { @@ -1973,15 +1879,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 @@ -1994,9 +1891,8 @@ int main( #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 ); @@ -2192,6 +2088,13 @@ cleanup: { free( bitsBufferData ); } +#endif +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( args.aeSequence.count > 0 ) + { + free( args.aeSequence.pID ); + free( args.aeSequence.pValidity ); + } #endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { @@ -2285,9 +2188,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 +2225,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; @@ -2673,6 +2564,94 @@ static bool parseLfePositionConfig( } +#ifdef FIX_1053_REVERB_RECONFIGURATION +static bool parseAcousticEnvironmentIds( + const char *value, + AcousticEnvironmentSequence *aeSequence ) +{ + uint16_t k; + char config_string[RENDERER_MAX_METADATA_LINE_LENGTH]; + char *s; + char *token; + + strncpy( config_string, value, RENDERER_MAX_METADATA_LINE_LENGTH ); + s = config_string; + token = config_string; + + if ( !is_digits_only( config_string ) ) + { + + for ( k = 0; s[k]; ) + { + s[k] == ',' ? k++ : *s++; + } + k++; + + if ( k == 0 ) + { + fprintf( stdout, "Error: Invalid acoustic environment sequence specified: %s\n\n", config_string ); + return false; + } + + if ( NULL == ( aeSequence->pID = malloc( sizeof( uint16_t ) * k ) ) || + NULL == ( aeSequence->pValidity = malloc( sizeof( uint16_t ) * k ) ) ) + { + fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", config_string ); + return false; + } + + aeSequence->count = k; + + k = 0; + + token = strtok( config_string, ":" ); + + while ( token != NULL ) + { + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, config_string ); + return false; + } + aeSequence->pID[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, "," ); + if ( !is_number( token ) ) + { + fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, config_string ); + return false; + } + aeSequence->pValidity[k] = (uint16_t) atoi( token ); + + token = strtok( NULL, ":" ); + k++; + } + + if ( k != aeSequence->count ) + { + fprintf( stdout, "Error while parsing acoustic environment sequence: %s\n\n", config_string ); + return false; + } + } + 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; +} +#endif + + static bool checkRequiredArgs( CmdlnArgs args ) { @@ -2687,18 +2666,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 ) { @@ -2789,7 +2760,15 @@ static CmdlnArgs defaultArgs( args.directivityPatternId[i] = 65535; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + args.aeSequence.count = 0; + args.aeSequence.pID = NULL; + args.aeSequence.pValidity = NULL; + args.aeSequence.selected = 0; + args.aeSequence.frameCounter = 0; +#else args.acousticEnvironmentId = 65535; +#endif return args; } @@ -2961,12 +2940,19 @@ static void parseOption( break; case CmdLnOptionId_acousticEnvironmentId: assert( numOptionValues == 1 ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( !parseAcousticEnvironmentIds( optionValues[0], &args->aeSequence ) ) + { + fprintf( stderr, "Invalid acoustic environment ID specified: %s\n", optionValues[0] ); + } +#else if ( !is_digits_only( optionValues[0] ) ) { fprintf( stderr, "Invalid acousting environment ID specified: %s\n", optionValues[0] ); exit( -1 ); } args->acousticEnvironmentId = (int16_t) strtol( optionValues[0], NULL, 10 ); +#endif break; case CmdLnOptionId_syncMdDelay: assert( numOptionValues == 1 ); diff --git a/ci/basop-pages/basop_index.html b/ci/basop-pages/basop_index.html new file mode 100644 index 0000000000000000000000000000000000000000..4c5202ad352c5821de0e106eee7100ac95d8fcd5 --- /dev/null +++ b/ci/basop-pages/basop_index.html @@ -0,0 +1,22 @@ + + + + + +

Ivas BASOP code Development

+ +

Daily long testvector tests

+ + + +

Test Coverage

+ +
+ tbd... +
+ + diff --git a/ci/basop-pages/create_report_pages.py b/ci/basop-pages/create_report_pages.py new file mode 100644 index 0000000000000000000000000000000000000000..ca14442edb6f41fa6297d2ef310da0a7361e5a25 --- /dev/null +++ b/ci/basop-pages/create_report_pages.py @@ -0,0 +1,219 @@ +import csv +import pathlib +import argparse + + +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
  • + + +
    +Table is sorted by Difference in MLD. +
    + + + + + + + + + + + + + + +{table_body} + +
    TestcaseMLDMax Abs Diff
    {id_previous}{id_current}{id_previous}{id_current}
    +""" +TD_TMPL_NORMAL = "{}" +TD_TMPL_INCREASE = "{}" +TD_TMPL_REDUCE = "{}" +TR_TMPL = "{}" + +# 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:] + + +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_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, + ) + 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}"] + + # use red background if increase, green if decrease, white if same + td_tmpl = TD_TMPL_NORMAL + try: + if float(curr) > float(prev): + td_tmpl = TD_TMPL_INCREASE + if float(curr) < float(prev): + td_tmpl = 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 = TD_TMPL_INCREASE + + tr.append(td_tmpl.format(row[f"{c}-{id_previous}"])) + tr.append(td_tmpl.format(row[f"{c}-{id_current}"])) + + 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}" + + # sort based on difference in MLD between current and previous run + # put cases with "None" at the top of the list + def sort_func(x): + vals_missing = ["None", ""] + + if x[mld_col_curr] in vals_missing or x[mld_col_prev] in vals_missing: + return float("inf") + + return float(x[mld_col_curr]) - float(x[mld_col_prev]) + + merged = sorted(merged, key=sort_func, 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 index 18943e918dd1a2a17370c41254a90166dc1852d1..3dea1a1200301d6cfd89c07f4811a901134dd627 100644 --- a/ci/check_self_test_names.py +++ b/ci/check_self_test_names.py @@ -45,7 +45,7 @@ if __name__ == "__main__": if skiplines > 0: skiplines = skiplines - 1 else: - if "//" in line and len(line) > args.max_length: + 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: diff --git a/ci/get_id_of_last_job_occurence.py b/ci/get_id_of_last_job_occurence.py index 449902f50a12919897ef0c0aaac41c197cd59f05..50beac5bb7c96d9b657604fb562e870bade65d68 100755 --- a/ci/get_id_of_last_job_occurence.py +++ b/ci/get_id_of_last_job_occurence.py @@ -1,49 +1,50 @@ #!/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" -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) @@ -61,7 +62,8 @@ def get_job_id(branch_name, job_name): # find actual job by name for job in resp_jobs.json(): - if job["name"] == job_name and job["status"] == "success": + include_job = not success_only or job["status"] == "success" + if include_job and job["name"] == job_name: job_id = job["id"] break if job_id >= 0: @@ -75,10 +77,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..4754d09f5c8d834e9f664aa63a73377b60473668 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,81 @@ JOBS = [ "complexity-StereoDmxEVS-stereo-in-mono-out", "coverage-test-on-main-scheduled", ] +JOBS_BASOP_REPO = [ + "ivas-pytest-mld-long-dec", +] + +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 +104,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 +117,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..07715a9ef4f78d1208634252d6911616b86c6ed4 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 *----------------------------------------------------------------------------------*/ @@ -201,9 +207,10 @@ typedef struct _IVAS_JBM_TRACE_DATA * Split rendering API constants, structures, and enums *----------------------------------------------------------------------------------*/ -#define IVAS_MAX_SPLIT_REND_BITRATE 768000 -#define IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) -#define IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define ISAR_MAX_SPLIT_REND_BITRATE 768000 +#define ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) ISAR_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) +#define ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define SPLIT_REND_BITS_BUFF_SIZE ( ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES + ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) typedef enum { @@ -215,64 +222,74 @@ typedef enum YAW_ROLL, PITCH_ROLL -} IVAS_SPLIT_REND_ROT_AXIS; +} ISAR_SPLIT_REND_ROT_AXIS; typedef enum { - IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, -} IVAS_SPLIT_REND_POSE_CORRECTION_MODE; +} ISAR_SPLIT_REND_POSE_CORRECTION_MODE; typedef enum { - IVAS_SPLIT_REND_CODEC_LCLD, - IVAS_SPLIT_REND_CODEC_LC3PLUS, - IVAS_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ - IVAS_SPLIT_REND_CODEC_NONE + ISAR_SPLIT_REND_CODEC_LCLD, + ISAR_SPLIT_REND_CODEC_LC3PLUS, + ISAR_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ + ISAR_SPLIT_REND_CODEC_NONE -} IVAS_SPLIT_REND_CODEC; +} ISAR_SPLIT_REND_CODEC; typedef enum { - IVAS_SPLIT_REND_RENDERER_SELECTION_CREND, - IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV, - IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, - IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND, - IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT, + ISAR_SPLIT_REND_RENDERER_SELECTION_CREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV, + ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, + ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT, -} IVAS_SPLIT_REND_RENDERER_SELECTION; +} ISAR_SPLIT_REND_RENDERER_SELECTION; -typedef struct _IVAS_SPLIT_REND_BITS_DATA +typedef struct _ISAR_SPLIT_REND_BITS_DATA { uint8_t *bits_buf; int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/ int32_t bits_written; int32_t bits_read; int16_t codec_frame_size_ms; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; +#endif -} IVAS_SPLIT_REND_BITS_DATA, *IVAS_SPLIT_REND_BITS_HANDLE; +} ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE; -typedef struct _IVAS_SPLIT_REND_CONFIG +typedef struct _ISAR_SPLIT_REND_CONFIG { - int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ - int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ - int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ - /*The axis can be set dynamically per frame based on a file input */ - /*possible values: - 1 - (1dof correction. By default YAW correction) - 2 - (2dof correction. By default YAW and PITCH correction) - 3 - (3dof correction. By default YAW, PITCH and ROLL correction) - */ - int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ - int16_t codec_frame_size_ms; /*Codec frame size in milliseconds, only relevant with LC3plus */ - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_RENDERER_SELECTION rendererSelection; - -} IVAS_SPLIT_REND_CONFIG_DATA; + int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ + int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ + int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ + /*The axis can be set dynamically per frame based on a file input */ + /*possible values: + 1 - (1dof correction. By default YAW correction) + 2 - (2dof correction. By default YAW and PITCH correction) + 3 - (3dof correction. By default YAW, PITCH and ROLL correction) + */ + int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; /* ISAR bit stream frame size in milliseconds */ +#endif + int16_t codec_frame_size_ms; /* Codec frame size in milliseconds, only relevant with LC3plus */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t lc3plus_highres; +#endif + +} ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE; #endif /*----------------------------------------------------------------------------------* @@ -315,10 +332,28 @@ typedef struct _IVAS_RENDER_CONFIG #endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; + ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; #endif float directivity[IVAS_MAX_NUM_OBJECTS * 3]; +#ifdef CONF_DISTATT + float distAtt[3]; +#endif } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; +typedef struct +{ + int16_t numSamplesPerChannel; + int16_t numChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t is_cldfb; +#endif +} IVAS_REND_AudioBufferConfig; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + float *data; +} IVAS_REND_AudioBuffer; + #endif /* COMMON_API_TYPES_H */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 8ebe56c1853a0c0977fc652faef66a4f2842b6f2..9d842f9b37eba0ba9ac5e8dd640e0bccd524bbf2 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,9 @@ typedef enum typedef enum { IVAS_FILTER_ORDER_1 = 1, +#ifndef NONBE_FIX_MC_LFE_LPF IVAS_FILTER_ORDER_2 = 2, +#endif IVAS_FILTER_ORDER_4 = 4, } ivas_filter_order; @@ -1481,18 +1475,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 +1517,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 +1720,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..a5fe2d93489bc23be1f379c829b9d7bd6f8f1a21 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -104,6 +104,12 @@ typedef enum * input data errors * *----------------------------------------*/ IVAS_ERR_INVALID_BITSTREAM = 0x2000, +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM, + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM_CONFIG, +#endif +#endif /*----------------------------------------* * hardware errors * diff --git a/lib_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..2c60e8743dfd7ab77e6d9c5c45e9ae0ac6488381 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters.c @@ -62,7 +62,11 @@ void ivas_filters_init( int16_t i; filter_state->order = order; +#ifdef NONBE_FIX_MC_LFE_LPF + if ( order == IVAS_FILTER_ORDER_1 ) +#else if ( order == IVAS_FILTER_ORDER_2 || order == IVAS_FILTER_ORDER_1 ) +#endif { filter_state->filt_len = order + 1; @@ -116,7 +120,9 @@ void ivas_filter_process( switch ( filter_state->order ) { case IVAS_FILTER_ORDER_1: +#ifndef NONBE_FIX_MC_LFE_LPF case IVAS_FILTER_ORDER_2: +#endif 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..34e3a9925c2134f988b55752d398c346e6add446 100644 --- a/lib_com/ivas_lfe_com.c +++ b/lib_com/ivas_lfe_com.c @@ -60,6 +60,7 @@ void ivas_lfe_lpf_select_filt_coeff( { switch ( order ) { +#ifndef NONBE_FIX_MC_LFE_LPF case IVAS_FILTER_ORDER_2: switch ( sampling_rate ) { @@ -76,6 +77,7 @@ void ivas_lfe_lpf_select_filt_coeff( break; } break; +#endif 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..c2bf977774330444627dcd4f290d320fae3bbe0b 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" @@ -981,20 +982,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] */ @@ -3212,7 +3207,10 @@ 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 */ +#ifdef NONBE_FIX_1052_SBA_EXT + const int16_t nchan_transport, /* i : number of transport channels */ +#endif + const int16_t ivas_format /* i : ivas format */ ); /*! r: number of bits read */ @@ -3520,6 +3518,13 @@ int16_t ivas_sba_get_nchan_metadata( const int32_t ivas_total_brate /* i : IVAS total bitrate */ ); +#ifdef NONBE_FIX_1052_SBA_EXT +/*! 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 */ +); +#endif + 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 +3626,10 @@ 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 */ +#ifdef NONBE_FIX_1052_SBA_EXT + const int16_t nchan_transport, /* i : number of transport channels */ +#endif + const int16_t hodirac_flag /* i : hodirac flag */ ); ivas_error ivas_dirac_config( @@ -3676,6 +3684,9 @@ 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 */ + #ifdef NONBE_FIX_1052_SBA_EXT + const int16_t nchan_transport, /* i : number of transport channels */ +#endif int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ); @@ -5506,7 +5517,11 @@ 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 */ +#ifdef NONBE_FIX_MC_LFE_LPF + const int32_t delay_ns /* i : additional LFE delay to sync other channel outputs */ +#else const int32_t binauralization_delay_ns /* i : additional LFE delay to sync with binaural renderer */ +#endif ); void ivas_lfe_dec_close( @@ -5613,7 +5628,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 *---------------------------------------------------------------------------------*/ @@ -5933,6 +5951,56 @@ int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ ); +void Euler2Quat( + const float yaw, /* i : yaw (x) */ + const float pitch, /* i : pitch (y) */ + const float roll, /* i : roll (z) */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +); + +float deg2rad( + float degrees +); + +#ifdef SPLIT_REND_WITH_HEAD_ROT +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); +#endif + +/*----------------------------------------------------------------------------------* + * Limiter prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_limiter_open( + IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ + const int16_t num_channels, /* i : number of I/O channels */ + const int32_t sampling_rate /* i : sampling rate for processing */ +); + +void ivas_limiter_close( + IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ +); + +void ivas_limiter_dec +( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ + const int16_t num_channels, /* i : number of channels to be processed */ + const int16_t output_frame, /* i : number of samples per channel in the buffer */ + const int16_t BER_detect /* i : BER detect flag */ +); + +void limiter_process( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ + const float threshold, /* i : signal amplitude above which limiting starts to be applied */ + const int16_t BER_detect, /* i : BER detect flag */ + int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ +); /* clang-format on */ diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 68169f10d49b4a1cc4bc5e5ca279438ae06d6571..c0c8de6ad5141392f4e4f3966c6899ca9165fc78 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -3079,6 +3079,7 @@ const float ivas_lpf_4_butter_48k_sos[IVAS_BIQUAD_FILT_LEN << 2] = 1.00000000471366f, 1.f , -1.98677297369091f, 0.987060670205863f }; +#ifndef NONBE_FIX_MC_LFE_LPF const float ivas_lpf_2_butter_16k[IVAS_BIQUAD_FILT_LEN << 1] = { 0.000628720643081143f, 0.00125744128616229f, 0.000628720643081143f, 1.f, -1.92783286977036f, 0.930347752342683f @@ -3093,7 +3094,7 @@ 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 }; - +#endif 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..a87d186465c880a6ddcb0e15cedd4ee4f1fba317 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -348,9 +348,11 @@ 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]; +#ifndef NONBE_FIX_MC_LFE_LPF 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]; +#endif 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..8497a871f638c178f0e5043e7cff1d1f81dcac6f --- /dev/null +++ b/lib_com/ivas_rotation_com.c @@ -0,0 +1,137 @@ +/****************************************************************************************************** + + (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; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * Quat2EulerDegree() + * + * Quaternion handling: calculate corresponding Euler angles in degrees + *------------------------------------------------------------------------*/ + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +) +{ + if ( quat.w != -3.0 ) + { + float p; + *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) ); + p = 2 * ( quat.w * quat.y - quat.z * quat.x ); + p = max( -1.0f, min( 1.0f, p ) ); + *pitch = asinf( p ); + *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) ); + *yaw *= _180_OVER_PI; + *pitch *= _180_OVER_PI; + *roll *= _180_OVER_PI; + } + else + { + /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention + * + * yaw: rotate scene counter-clockwise in the horizontal plane + * pitch: rotate scene in the median plane, increase elevation with positive values + * roll: rotate scene from the right ear to the top + */ + *yaw = quat.z; + *pitch = quat.y; + *roll = quat.x; + } + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * deg2rad() + * + * Converts degrees to normalized radians + *------------------------------------------------------------------------*/ + +float deg2rad( + float degrees ) +{ + while ( degrees >= 180.0f ) + { + degrees = degrees - 360.0f; + } + while ( degrees <= -180.0f ) + { + degrees = degrees + 360.0f; + } + + return PI_OVER_180 * degrees; +} diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index cb573d7f28580224703b477feb63cbef0a5b8c79..a622d8f88fc69249d77eba8c4055f588bb8b68fc 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -158,6 +158,29 @@ int16_t ivas_sba_get_nchan( return ( nb_channels ); } +#ifdef NONBE_FIX_1052_SBA_EXT +/*-------------------------------------------------------------------* + * 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; +} +#endif /*-------------------------------------------------------------------* * 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 f417a679526265a01751dda47282793648dde493..6c4363df1775edf2e1fcac6b2c6b395dd8ed9ad1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -154,10 +154,27 @@ /* 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 SPLIT_REND_WITH_HEAD_ROT /* Dlb,FhG: Split Rendering contributions 21 and 35 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define ISAR_BITSTREAM_UPDATE_LC3PLUS /* FhG: Multiple improvements to the ISAR bitstream when LC3plus is used. See MR 1456 for details. */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#define LC3PLUS_LEA_COMPAT_BITRATES_48_6 /* FhG: treat split-rendering 256kbps lc3plus 10ms 0dof bitrate as sentinel value for LEA compatible 48_6 bitrate (124 kbps per channel) */ +#endif +#define SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +#define FIX_1081_BINAURAL_SPLIT_PCM_SANITY_CHECK /* VA: issue 1081: correct error print-out when BINAURAL_SPLIT_PCM is requested */ +#endif -#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_1053_REVERB_RECONFIGURATION /* Philips: issue 1053: fix for dynamic switching of acoustic environment */ +#define CONF_DISTATT /* Eri: Make distance attenuation configurable */ +#define FIX_1082_INSTRUM_FAILED_LC3PLUS /* VoiceAge: issue 1082: fix ambiguous syntax in LC3Plus code leading to fails of instrumented builds */ +#define FIX_1052_EXT_OUTPUT /* VA: issue 1052: define EXT decoder output configuration for stereo and MC formats */ +#define FIX_989_TD_REND_ROM /* Eri: Clean-up for TD renderer and completion of ROM generation tool */ + +#define FIX_1068_ASAN_IN_MC_2_BINAURAL_ROOM_IR /* issue 1068 : Memory leak in MC to BINAURAL_ROOM decoding with bitrate switching*/ /* #################### End BE switches ################################## */ @@ -165,10 +182,14 @@ /* 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_ISM_XOVER_BR /* FhG: issue 1072: select OSBA coding method depending on number of object and bitrate */ +#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*/ +#define NONBE_FIX_MC_LFE_LPF /* Dlb: Adding the LFE LPF filter back for MC content. */ +#define NONBE_FIX_1052_SBA_EXT /* Dlb: SBA external output support */ +#define NONBE_FIX_1069_SVD_TUNING /* FhG: issue 1069: tune SVD constants */ +#define NONBE_FIX_1087_OOB_SBA_DTX_RS /* VA: issue 1087: Extend the length of the buffer for MCT decoding to avoid out-of-bound writing in SBA SID bitrate switching decoding */ +#define NONBE_FIX_1091_PMC_LOW_SIGNAL_BURSTS /* FhG: fix for #1091, fix limit calculation for the regularized inverse of Kx to avoid bursts in very low signals */ +#define NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR /* Nok: issue 1074 fixing number of objects signaling in OMASA low rate */ /* ##################### End NON-BE switches ########################### */ /* ################## End DEVELOPMENT switches ######################### */ 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..d1d2d6f7bcf28925ad4bccd3f4a4f0896213e934 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -42,15 +42,24 @@ #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" +#ifdef FIX_1053_REVERB_RECONFIGURATION + +/*------------------------------------------------------------------------- + * 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 }, +}; +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_filterModule() @@ -895,7 +904,11 @@ static void ivas_binaural_obtain_DMX( for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { +#ifdef FIX_1053_REVERB_RECONFIGURATION + float dmxConst = dmxmtx_table[chOutIdx][chIdx]; +#else float dmxConst = hBinRenderer->hReverb->dmxmtx[chOutIdx][chIdx]; +#endif for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -1104,7 +1117,11 @@ ivas_error ivas_binRenderer_open( ) { BINAURAL_RENDERER_HANDLE hBinRenderer; +#ifdef FIX_1053_REVERB_RECONFIGURATION + int16_t convBand, k; +#else int16_t convBand, chIdx, k; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -1131,9 +1148,9 @@ ivas_error ivas_binRenderer_open( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses + 1; + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses + 1; #else - hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; #endif } else @@ -1259,7 +1276,7 @@ ivas_error ivas_binRenderer_open( { return error; } - +#ifndef FIX_1053_REVERB_RECONFIGURATION /* initialize the dmx matrix */ if ( hBinRenderer->nInChannels != HOA3_CHANNELS ) { @@ -1271,6 +1288,7 @@ ivas_error ivas_binRenderer_open( } } } +#endif } else { @@ -1659,14 +1677,14 @@ 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 @@ -1676,7 +1694,7 @@ void ivas_binaural_cldfb( ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, JBM_CLDFB_SLOTS_IN_SUBFRAME, @@ -1718,8 +1736,8 @@ 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 ); } } } @@ -1837,14 +1855,14 @@ void ivas_binaural_cldfb_sf( } #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 } @@ -1855,7 +1873,7 @@ void ivas_binaural_cldfb_sf( ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], @@ -1877,8 +1895,8 @@ 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 ); } } } @@ -1948,6 +1966,8 @@ void ivas_binRenderer( int16_t chIdx, k; #ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx, num_poses; + float RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; #endif push_wmops( "fastconv_binaural_rendering" ); @@ -1969,6 +1989,15 @@ void ivas_binRenderer( } } } + + for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + mvr2r( RealBuffer[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + mvr2r( ImagBuffer[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } #else for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { @@ -2015,7 +2044,6 @@ void ivas_binRenderer( #endif #ifdef SPLIT_REND_WITH_HEAD_ROT - /*TODO : move this to a separate function*/ if ( pMultiBinPoseData != NULL ) { if ( pMultiBinPoseData->num_poses > 1 ) @@ -2026,12 +2054,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 +2087,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,27 +2100,6 @@ void ivas_binRenderer( ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, pos_idx ); } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - if ( hPostRendHeadTrackData != NULL ) - { - IVAS_QUATERNION *Quaternions_new1; - IVAS_QUATERNION Quaternions_new; - Quaternions_new1 = &hPostRendHeadTrackData->Quaternions[hPostRendHeadTrackData->num_quaternions++]; - Quaternions_new.w = -3.0f; /*euler*/ - Quat2EulerDegree( *Quaternions_new1, &Quaternions_new.z, &Quaternions_new.y, &Quaternions_new.x ); /*order in Quat2Euler seems to be reversed ?*/ - Quaternions_rel.x = Quaternions_new.x - Quaternions_abs.x; - Quaternions_rel.y = Quaternions_new.y - Quaternions_abs.y; - Quaternions_rel.z = Quaternions_new.z - Quaternions_abs.z; - Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; - Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; - Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; - - QuatToRotMat( Quaternions_rel, Rmat_local ); - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, 3 ); - ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[num_poses], Cldfb_ImagBuffer_Binaural[num_poses], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, num_poses ); - } -#endif } } } @@ -2170,7 +2197,7 @@ void ivas_rend_CldfbMultiBinRendProcess( if ( ( *pCombinedOrientationData ) != NULL ) { - if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0]; for ( i = 0; i < 3; i++ ) diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index fd7ce6c8037640251469e0ae619931b6c30f26e0..5f5e787c9407a72f4d6061cc9294fd8e1d4d911d 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -270,7 +270,11 @@ ivas_error ivas_corecoder_dec_reconfig( } else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + if ( ( error = mct_dec_reconfigure( st_ivas, nchan_transport_real != nchan_transport_old ) ) != IVAS_ERR_OK ) +#else if ( ( error = mct_dec_reconfigure( st_ivas, st_ivas->nchan_transport != nchan_transport_old ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -351,7 +355,11 @@ ivas_error ivas_corecoder_dec_reconfig( * Set CNA/CNG flags *-----------------------------------------------------------------*/ +#ifdef NONBE_FIX_ISM_XOVER_BR + if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) +#else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) +#endif { 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..bbbd8d9f97974ca5f2d0fc60c46e8eb20c906fba 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -765,6 +765,9 @@ ivas_error ivas_dirac_dec_config( int16_t need_parambin; int16_t dec_param_estim_old; int16_t dec_param_estim_new; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t num_poses, pos_idx; +#endif error = IVAS_ERR_OK; @@ -775,6 +778,14 @@ ivas_error ivas_dirac_dec_config( hodirac_flag = ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); dec_param_estim_old = ( dec_config_flag == DIRAC_RECONFIGURE ) ? st_ivas->hDirAC->hConfig->dec_param_estim : FALSE; +#ifdef SPLIT_REND_WITH_HEAD_ROT + num_poses = 1; + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + } +#endif + sparfoa_flag = 0; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA && st_ivas->ivas_format == SBA_FORMAT && !hodirac_flag ) { @@ -904,7 +915,7 @@ ivas_error ivas_dirac_dec_config( #ifdef SPLIT_REND_WITH_HEAD_ROT /* copy td-decorr flag to split renderer side rendereres */ - for ( int16_t pos_idx = 1; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 1; pos_idx < num_poses; pos_idx++ ) { st_ivas->hDiracDecBin[pos_idx]->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; } @@ -925,12 +936,13 @@ ivas_error ivas_dirac_dec_config( ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); + if ( ( error = ivas_dirac_dec_decorr_open( #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, #else - if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, #endif - DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -938,7 +950,7 @@ ivas_error ivas_dirac_dec_config( } #ifdef SPLIT_REND_WITH_HEAD_ROT - for ( int16_t pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); } @@ -1001,7 +1013,10 @@ 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 */ - int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ +#ifdef NONBE_FIX_1052_SBA_EXT + const int16_t nchan_transport, /* i : number of transport channels */ +#endif + int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ) { int16_t i, j, b, dir, orig_dirac_bands; @@ -1034,7 +1049,12 @@ void ivas_dirac_dec_read_BS( } } +#ifdef NONBE_FIX_1052_SBA_EXT + *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), nchan_transport, NULL, SBA_FORMAT ); +#else *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ); +#endif + 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 +1102,11 @@ 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 */ +#ifdef NONBE_FIX_1052_SBA_EXT + st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS - SBA_PLANAR_BITS - SBA_ORDER_BITS ); +#else st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS ); +#endif /* 1 bit flag for signaling metadata to read */ b = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits )++; @@ -1102,7 +1126,11 @@ void ivas_dirac_dec_read_BS( } } +#ifdef NONBE_FIX_1052_SBA_EXT + *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), nchan_transport, NULL, SBA_FORMAT ); +#else *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ); +#endif 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]; @@ -2317,13 +2345,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; } @@ -2342,17 +2365,17 @@ void ivas_dirac_dec_render_sf( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { for ( ch = 0; ch < st_ivas->hBinRenderer->nInChannels; ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } #endif @@ -2360,7 +2383,7 @@ void ivas_dirac_dec_render_sf( /* Perform binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, @@ -2379,8 +2402,8 @@ void ivas_dirac_dec_render_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); } } } diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index 7afa191edbd15d72c047461ba1e2709e3a9b818a..00d7b2b7760194cef062e42b2e7b4ed1b0345019 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -51,6 +51,13 @@ #include "wmc_auto.h" #include "rom_dec.h" +#ifdef NONBE_FIX_1091_PMC_LOW_SIGNAL_BURSTS +/*-----------------------------------------------------------------------* + * Local constants + *-----------------------------------------------------------------------*/ + +#define SQRT_EPSILON 3.16227755e-08 /* square root of EPSILON */ +#endif /*-------------------------------------------------------------------* * ivas_dirac_dec_output_synthesis_cov_open() @@ -577,8 +584,11 @@ int16_t computeMixingMatrices( *-----------------------------------------------------------------*/ maximum( svd_s_buffer, lengthCx, &limit ); +#ifdef NONBE_FIX_1091_PMC_LOW_SIGNAL_BURSTS + limit = (float) max( limit * reg_Sx, SQRT_EPSILON ); +#else limit = limit * reg_Sx + EPSILON; - +#endif 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..9b29070053204464818ffc59ee636f6e353c9597 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -38,7 +38,9 @@ #include "ivas_stat_enc.h" #include "prot.h" #ifdef SPLIT_REND_WITH_HEAD_ROT -#include "common_api_types.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#include "isar_stat.h" #endif #include #include @@ -57,6 +59,10 @@ 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 NONBE_FIX_1052_SBA_EXT +static AUDIO_CONFIG ivas_set_output_config_from_sba_order( const int16_t sba_order ); +#endif + #ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas ); @@ -74,11 +80,8 @@ static ivas_error ivas_dec_reconfig_split_rend( ivas_error error; int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; SPLIT_REND_WRAPPER *hSplitRendWrapper; -#ifndef SPLIT_REND_WITH_HEAD_ROT - CLDFB_TYPE cldfbMode; -#endif - hSplitRendWrapper = &st_ivas->hSplitBinRend.splitrend; + hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; cldfb_in_flag = 0; @@ -90,42 +93,35 @@ static ivas_error ivas_dec_reconfig_split_rend( cldfb_in_flag = 1; } - ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); isCldfbNeeded = 0; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#else - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) + + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { cldfb_in_flag = 0; } -#endif if ( st_ivas->renderer_type != RENDERER_DISABLE ) { if ( cldfb_in_flag == 0 ) { isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif } - else if ( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) { isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_SYNTHESIS; -#endif } else if ( pcm_out_flag && cldfb_in_flag ) { isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_SYNTHESIS; -#endif } } + else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + isCldfbNeeded = 1; + } if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) { @@ -144,18 +140,12 @@ static ivas_error ivas_dec_reconfig_split_rend( for ( ch = 0; ch < num_ch; ch++ ) { -#ifndef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), cldfbMode, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) -#else if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) -#endif - { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) @@ -163,7 +153,6 @@ static ivas_error ivas_dec_reconfig_split_rend( return error; } } -#endif } else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) { @@ -177,7 +166,6 @@ static ivas_error ivas_dec_reconfig_split_rend( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) @@ -186,25 +174,21 @@ static ivas_error ivas_dec_reconfig_split_rend( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; } } -#endif free( hSplitRendWrapper->hCldfbHandles ); hSplitRendWrapper->hCldfbHandles = NULL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && - ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) ) -#else - if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) -#endif + ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && + !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) /* td-rend not needed? */ { for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - if ( hSplitRendWrapper->hTdRendHandles[i] != NULL ) + if ( st_ivas->hTdRendHandles[i] != NULL ) { - hSplitRendWrapper->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &hSplitRendWrapper->hTdRendHandles[i] ); + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); } } } @@ -225,6 +209,7 @@ static ivas_error ivas_dec_init_split_rend( { ivas_error error; int16_t cldfb_in_flag, pcm_out_flag; + int16_t mixed_td_cldfb_flag; pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; cldfb_in_flag = 0; @@ -237,33 +222,50 @@ static ivas_error ivas_dec_init_split_rend( cldfb_in_flag = 1; } - ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); - if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend.splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) { - if ( ( st_ivas->hSplitBinRend.hCldfbDataOut = (IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); } } - if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, (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 ) + 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 ) ) { - cldfb_in_flag = 0; + mixed_td_cldfb_flag = 1; } -#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 ); + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_framesize, mixed_td_cldfb_flag ); return error; } #endif +#ifdef NONBE_FIX_1052_SBA_EXT +static AUDIO_CONFIG ivas_set_output_config_from_sba_order( const int16_t sba_order ) +{ + AUDIO_CONFIG output_config; + output_config = IVAS_AUDIO_CONFIG_HOA3; + switch ( sba_order ) + { + 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 ); + } + return output_config; +} +#endif /*-------------------------------------------------------------------* * ivas_dec_setup() @@ -351,6 +353,13 @@ 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]; +#ifdef NONBE_FIX_1052_SBA_EXT + 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 ); + } +#endif num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) @@ -390,12 +399,30 @@ ivas_error ivas_dec_setup( if ( st_ivas->nchan_ism > 0 ) { +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + /* the input_ivas_format should be MASA_ISM_FORMAT, but we cannot initialize it now */ + /* 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 = 1; + } + /* for MASA_ISM_FORMAT at input the number of MASA transport channels is always 2 and the corresponding bit is not used here*/ +#else /* 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 ) { st_ivas->nchan_ism = 4; } + /* for MASA_ISM_FORMAT at input the number of MASA transport channels is always 2 */ +#endif st_ivas->nchan_transport = 2; element_mode_flag = 1; } @@ -468,23 +495,22 @@ 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 @@ -506,11 +532,23 @@ 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 ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + { + int16_t n; + + n = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( n + 1 ) >> 1; + } +#else st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; +#endif } } - +#ifdef NONBE_FIX_ISM_XOVER_BR + if ( ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ) == ISM_SBA_MODE_DISC ) +#else if ( ivas_total_brate >= IVAS_256k ) +#endif { st_ivas->ism_mode = ISM_SBA_MODE_DISC; } @@ -607,6 +645,14 @@ ivas_error ivas_dec_setup( break; } +#ifdef NONBE_FIX_1052_SBA_EXT + 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 ); + } +#endif + if ( st_ivas->ini_frame > 0 && st_ivas->ivas_format == SBA_FORMAT ) { int16_t nchan_transport_old, nchan_transport; @@ -801,7 +847,6 @@ static ivas_error ivas_read_format( st_ivas->ivas_format = MASA_ISM_FORMAT; } } - ( *num_bits_read )++; } break; @@ -884,6 +929,16 @@ static ivas_error ivas_read_format( if ( st_ivas->ivas_format == SBA_FORMAT ) { +#ifdef NONBE_FIX_1052_SBA_EXT + /* 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; +#endif if ( st_ivas->sba_analysis_order == 0 ) { st_ivas->sba_analysis_order = SBA_FOA_ORDER; @@ -1093,7 +1148,8 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB #ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM + || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) #endif ) { @@ -1127,7 +1183,11 @@ ivas_error ivas_init_decoder( int16_t numCldfbAnalyses, numCldfbSyntheses; int16_t granularity, n_channels_transport_jbm; int32_t output_Fs, ivas_total_brate; +#ifdef NONBE_FIX_MC_LFE_LPF + int32_t delay_ns; +#else int32_t binauralization_delay_ns; +#endif AUDIO_CONFIG output_config; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -1149,7 +1209,19 @@ ivas_error ivas_init_decoder( if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { +#ifdef FIX_1052_EXT_OUTPUT + 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 ) +#else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) +#endif { hDecoderConfig->nchan_out = audioCfg2channels( IVAS_AUDIO_CONFIG_HOA3 ); hDecoderConfig->nchan_out += st_ivas->nchan_ism; @@ -1172,7 +1244,19 @@ ivas_error ivas_init_decoder( st_ivas->intern_config = output_config; +#ifdef FIX_1052_EXT_OUTPUT + 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 ); + } +#else ivas_output_init( &( st_ivas->hOutSetup ), output_config ); +#endif if ( st_ivas->ivas_format == SBA_ISM_FORMAT && output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { @@ -1255,17 +1339,14 @@ ivas_error ivas_init_decoder( * Initialize binuaral split rendering *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( st_ivas->hSplitBinRend != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) ) { if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - else - { - st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses = 1; - } #endif /*-----------------------------------------------------------------* @@ -1336,11 +1417,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 +1668,16 @@ ivas_error ivas_init_decoder( if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + { + int16_t n_all; + + n_all = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( n_all + 1 ) >> 1; + } +#else st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; +#endif st_ivas->element_mode_init = IVAS_CPE_MDCT; } @@ -1674,7 +1760,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 +1769,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 ) { @@ -2060,7 +2142,7 @@ ivas_error ivas_init_decoder( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, - st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + 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 ) #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 ) @@ -2192,8 +2274,9 @@ ivas_error ivas_init_decoder( } } +#ifndef NONBE_FIX_MC_LFE_LPF /*-----------------------------------------------------------------* - * LFE handles for rendering after rendering to adjust LFE delay to binaural filter delay + * 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 ) @@ -2225,7 +2308,7 @@ ivas_error ivas_init_decoder( set_zero( st_ivas->hLFE->prevsynth_buf, LFE_PLC_BUFLEN ); set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k ); } - +#endif /*-----------------------------------------------------------------* * CLDFB handles for rendering *-----------------------------------------------------------------*/ @@ -2262,6 +2345,49 @@ ivas_error ivas_init_decoder( ivas_spar_get_cldfb_gains( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); } +#ifdef NONBE_FIX_MC_LFE_LPF + /*-----------------------------------------------------------------* + * 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 ) + { +#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 */ + 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 ); + } +#endif + /*-----------------------------------------------------------------* * Allocate and initialize limiter struct *-----------------------------------------------------------------*/ @@ -2563,11 +2689,11 @@ void ivas_initialize_handles_dec( st_ivas->hCombinedOrientationData = NULL; #ifdef SPLIT_REND_WITH_HEAD_ROT - st_ivas->hSplitBinRend.hMultiBinCldfbData = NULL; - st_ivas->hSplitBinRend.hSplitRendBits = NULL; - st_ivas->hSplitBinRend.hCldfbDataOut = NULL; - st_ivas->hSplitBinRend.numTdSamplesPerChannelCached = 0; - ivas_init_split_rend_handles( &st_ivas->hSplitBinRend.splitrend ); + st_ivas->hSplitBinRend = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + st_ivas->hTdRendHandles[i] = NULL; + } #endif /* JBM handles */ @@ -2707,13 +2833,14 @@ void ivas_destroy_dec( ivas_binRenderer_close( &st_ivas->hBinRenderer ); #ifdef SPLIT_REND_WITH_HEAD_ROT - /* Split binaural renderer handle */ - ivas_split_renderer_close( &st_ivas->hSplitBinRend.splitrend ); - - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + /* TD binaural renderer handles */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - free( st_ivas->hSplitBinRend.hCldfbDataOut ); - st_ivas->hSplitBinRend.hCldfbDataOut = NULL; + if ( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); + } } #endif @@ -2727,7 +2854,7 @@ void ivas_destroy_dec( /* Crend handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); #else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); #endif @@ -3090,11 +3217,25 @@ static ivas_error doSanityChecks_IVAS( /* Verify stereo output configuration */ if ( st_ivas->ivas_format == STEREO_FORMAT ) { +#ifdef FIX_1052_EXT_OUTPUT + 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 ) +#else 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 ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Wrong output configuration specified for Stereo!" ); } } +#ifdef FIX_1052_EXT_OUTPUT + /* 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!" ); + } + } +#else else if ( st_ivas->ivas_format == ISM_FORMAT ) { /* Verify ISM output configuration */ @@ -3126,6 +3267,7 @@ static ivas_error doSanityChecks_IVAS( return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for Multi-channel" ); } } +#endif #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 ) diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index ef13d2463db77908b7b861b266ccc3e96dd50ffd..35752bdd225c23812dd3809f7ef659b216ed17c0 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -231,7 +231,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* Open Crend Binaural renderer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) #endif @@ -270,25 +270,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 { @@ -311,7 +298,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* close the crend binaural renderer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); #else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); #endif diff --git a/lib_dec/ivas_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_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index ffb018c06d4f81d650214947b9fcb251a3f60d9a..883f170d608f7a00ba4dac9208d2d386e011bf5e 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -681,7 +681,11 @@ 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 || +#ifdef FIX_1052_EXT_OUTPUT + 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 ) +#else output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) +#endif { ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL ); } @@ -939,7 +943,14 @@ 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 ); +#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 + 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 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } } } @@ -1325,7 +1336,7 @@ ivas_error ivas_jbm_dec_render( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -1490,7 +1501,7 @@ ivas_error ivas_jbm_dec_render( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; } else { @@ -1658,14 +1669,37 @@ 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 ) { +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT +#if defined SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, 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, crendInPlaceRotation ? p_output : st_ivas->hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + +#endif +#else #if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif #endif { return error; @@ -2305,7 +2339,11 @@ ivas_error ivas_jbm_dec_tc_buffer_open( const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ ) { +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT + int32_t nsamp_to_allocate; +#else int16_t nsamp_to_allocate; +#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; int16_t nMaxSlotsPerSubframe; int16_t nchan_residual; @@ -2384,7 +2422,11 @@ ivas_error ivas_jbm_dec_tc_buffer_open( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); } +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT + set_zero_l( hTcBuffer->tc_buffer, nsamp_to_allocate ); +#else set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); +#endif offset = 0; for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) @@ -2430,7 +2472,12 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */ ) { +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT + int32_t nsamp_to_allocate, offset; + int16_t n_samp_full, n_samp_residual, nchan_residual; +#else int16_t nsamp_to_allocate, n_samp_full, n_samp_residual, offset, nchan_residual; +#endif int16_t ch_idx; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -2517,7 +2564,11 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); } +#ifdef NONBE_FIX_1070_USAN_SEGFAULT_MC_TO_BIN_BTSW_HEADROT + set_zero_l( hTcBuffer->tc_buffer, nsamp_to_allocate ); +#else set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); +#endif offset = 0; for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c index 83b196190730ff0f18693f872607393e88b75f47..f672fe75ec292a085238bda5db82b31ebf93dc83 100644 --- a/lib_dec/ivas_lfe_dec.c +++ b/lib_dec/ivas_lfe_dec.c @@ -252,6 +252,28 @@ static int16_t ivas_lfe_dec_dequant( } +#ifdef NONBE_FIX_MC_LFE_LPF +/*------------------------------------------------------------------------- + * 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; +} +#endif + + /*-----------------------------------------------------------------------------------------* * Function ivas_lfe_dec() * @@ -350,9 +372,15 @@ void ivas_lfe_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_create_lfe_dec( +#ifdef NONBE_FIX_MC_LFE_LPF + 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 */ +#else 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 */ +#endif ) { float low_pass_delay_dec_out, block_offset_s; @@ -403,6 +431,15 @@ ivas_error ivas_create_lfe_dec( block_offset_s = BLOCK_OFFSET_MS * 0.001f; filt_order = 0; low_pass_delay_dec_out = 0; +#ifdef NONBE_FIX_MC_LFE_LPF + 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 ); + } +#endif + 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 +448,11 @@ 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 ); +#ifdef NONBE_FIX_MC_LFE_LPF + add_delay_sa = (int16_t) roundf( (float) delay_ns * output_Fs / 1000000000.f ); +#else add_delay_sa = (int16_t) roundf( (float) binauralization_delay_ns * output_Fs / 1000000000.f ); +#endif 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..c1542e3d8babc4d710abbd94845c9041d097b627 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -151,73 +151,94 @@ ivas_error ivas_masa_decode( { if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) { - if ( ivas_format != MASA_ISM_FORMAT ) +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + 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 + { +#endif + 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 +247,82 @@ 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: +#ifndef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + /* 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 )--]; + '11' - MASA_ISM_FORMAT at the encoder, with 3 or 4 objects; reading if 3 or 4 object is performed later + */ +#endif + 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 ); +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + } +#endif } else { @@ -397,7 +447,11 @@ ivas_error ivas_masa_decode( hMasa->config.coherencePresent = !hQMetaData->all_coherence_zero; +#ifdef FIX_1052_EXT_OUTPUT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL && ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) ) +#else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) +#endif { index_16bits( hQMetaData, hMasa->data.sph_grid16 ); } @@ -617,7 +671,11 @@ ivas_error ivas_masa_dec_open( hMasa->config.joinedSubframes = FALSE; /* Create spherical grid only for external output */ +#ifdef FIX_1052_EXT_OUTPUT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL && ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) ) +#else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) +#endif { if ( ( hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL ) { @@ -1048,6 +1106,9 @@ 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 || +#ifdef FIX_1052_EXT_OUTPUT + output_config == IVAS_AUDIO_CONFIG_EXTERNAL || +#endif 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 ) ) ) @@ -1413,18 +1474,17 @@ ivas_error ivas_masa_dec_reconfigure( { if ( st_ivas->hDiracDecBin[pos_idx] != NULL ) { -#else - if ( st_ivas->hDiracDecBin != NULL ) - { -#endif /* regularization factor is bitrate-dependent */ -#ifdef SPLIT_REND_WITH_HEAD_ROT st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); } + } #else + if ( st_ivas->hDiracDecBin != NULL ) + { + /* regularization factor is bitrate-dependent */ st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif } +#endif if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */ { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 4e709162129b182f9db51afe4e8aa26758016e30..5742d41f70787533576fcfe6e5f31201515dbed0 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -148,7 +148,11 @@ ivas_error ivas_param_mc_dec_open( hParamMC->hoa_encoder = NULL; /* determine the synthesis config */ +#ifdef FIX_1052_EXT_OUTPUT + 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 ) +#else 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 ) +#endif { hParamMC->synthesis_conf = PARAM_MC_SYNTH_DIRECT; } @@ -1689,24 +1693,24 @@ void ivas_param_mc_dec_render( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } #endif ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG NULL, #endif @@ -1725,8 +1729,8 @@ void ivas_param_mc_dec_render( { for ( ch = 0; ch < nchan_out_cldfb; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); } } } diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index d6b12947ef70498e08ca2123987f5594d6272c69..a13d08297a2eae3133b4d3501e9972083c8fe5b3 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -761,18 +761,18 @@ static void ivas_mc_paramupmix_dec_sf( /*LFE handling for split rendering cases*/ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } #endif @@ -780,7 +780,7 @@ static void ivas_mc_paramupmix_dec_sf( /* Implement binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], @@ -798,8 +798,8 @@ static void ivas_mc_paramupmix_dec_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); } } } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 368f6e76b73251af322a48132a5a3ed6dca9ad0f..20e40412de2d8430748850d5fa0ea40ef309484e 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -87,6 +87,9 @@ ivas_error ivas_mct_dec( STnsData tnsData[MCT_MAX_BLOCKS][CPE_CHANNELS][NB_DIV]; Decoder_State **sts; float synth[CPE_CHANNELS][L_FRAME_PLUS]; +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + float *p_output_orig[2]; +#endif float output_lfe_ch[L_FRAME48k]; int32_t ivas_total_brate; ivas_error error; @@ -148,6 +151,18 @@ 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 ); +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + /* 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]; + } + } +#endif + for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) { st_ivas->hCPE[cpe_id]->hCoreCoder[0]->BER_detect |= st_ivas->BER_detect; @@ -232,6 +247,17 @@ ivas_error ivas_mct_dec( ivas_mdct_core_reconstruct( hCPE, x, synth, fUseTns[cpe_id], 1 ); +#ifdef NONBE_FIX_1087_OOB_SBA_DTX_RS + /* 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]; + } + } + +#endif /*----------------------------------------------------------------* * CoreCoder Post-processing and updates *----------------------------------------------------------------*/ @@ -263,7 +289,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 ) ) { @@ -673,6 +698,15 @@ ivas_error ivas_mc_dec_config( { st_ivas->transport_config = signaled_config; } +#ifdef FIX_1052_EXT_OUTPUT + 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!" ); + } +#endif /* 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,7 +714,11 @@ ivas_error ivas_mc_dec_config( /* MC format switching */ if ( st_ivas->ini_frame != 0 ) { +#ifdef FIX_1052_EXT_OUTPUT + if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || last_mc_mode != st_ivas->mc_mode ) +#else 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 ) +#endif { #ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) @@ -1117,21 +1155,46 @@ 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 ) { +#ifdef NONBE_FIX_MC_LFE_LPF + int32_t delay_ns = st_ivas->binaural_latency_ns; +#else int32_t binauralization_delay_ns = st_ivas->binaural_latency_ns; +#endif if ( st_ivas->hBinRenderer != NULL ) { if ( st_ivas->hBinRenderer->render_lfe ) { /* Account for filterbank delay */ +#ifdef NONBE_FIX_MC_LFE_LPF + delay_ns += IVAS_FB_DEC_DELAY_NS; +#else binauralization_delay_ns += IVAS_FB_DEC_DELAY_NS; +#endif } else { +#ifdef NONBE_FIX_MC_LFE_LPF + delay_ns = 0; +#else binauralization_delay_ns = 0; +#endif + } + } +#ifdef NONBE_FIX_MC_LFE_LPF + else + { + if ( ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && ( st_ivas->cldfbSynDec[0] != NULL ) ) + { + delay_ns += IVAS_FB_DEC_DELAY_NS; } } +#endif +#ifdef NONBE_FIX_MC_LFE_LPF + if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, delay_ns ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_create_lfe_dec( &st_ivas->hLFE, st_ivas->hDecoderConfig->output_Fs, binauralization_delay_ns ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1192,6 +1255,12 @@ static ivas_error ivas_mc_dec_reconfig( 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 ); +#ifdef FIX_1068_ASAN_IN_MC_2_BINAURAL_ROOM_IR + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) + { + efap_free_data( &st_ivas->hEFAPdata ); + } +#endif } #ifdef SPLIT_REND_WITH_HEAD_ROT @@ -1202,7 +1271,7 @@ static ivas_error ivas_mc_dec_reconfig( { #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); #else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); #endif @@ -1210,15 +1279,7 @@ static ivas_error ivas_mc_dec_reconfig( 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 @@ -1291,7 +1352,7 @@ static ivas_error ivas_mc_dec_reconfig( else if ( st_ivas->hCrendWrapper == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) #endif diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 907affdae1d5362ccf35bbd4a117f0566d4c23f3..4f0bd1044b33b08efca1d1785091839a772aee15 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -61,8 +61,13 @@ ivas_error ivas_td_binaural_open( num_src = st_ivas->nchan_ism; } +#ifdef CONF_DISTATT + 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->hRenderConfig->distAtt, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns ); +#else 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 ); +#endif } @@ -238,9 +243,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 +257,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 +276,11 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity, +#ifdef CONF_DISTATT + st_ivas->hRenderConfig->distAtt, +#endif 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 +341,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 ) diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index cfef5d17cac687a6d3e64865155edbdaed604fdf..2e464e1641a66332561423f881ecf93600867b4e 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -300,7 +300,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 +314,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 +328,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 +409,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 ); } @@ -783,6 +757,11 @@ 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]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; +#endif for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) { @@ -794,15 +773,56 @@ 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 ) +#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 ) { - 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 ); +#endif + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } - +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 7473cbaa75b21657e10829c9737edc16e54236b7..cca48cd7041d19e0eb99c1db40c4f910166ddea7 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -137,6 +137,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV float *p_sepobj[BINAURAL_CHANNELS]; int16_t channel_offset; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; +#endif for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { @@ -150,19 +155,21 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( return error; } +#ifdef NONBE_FIX_ISM_XOVER_BR + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig; - int16_t cldfb_slots, slot_idx_start; + int16_t cldfb_slots; float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - num_cldfb_bands = st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; nchan_transport_orig = st_ivas->nchan_transport; st_ivas->nchan_transport = st_ivas->nchan_ism; - slot_idx_start = st_ivas->hTcBuffer->n_samples_rendered / num_cldfb_bands; if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; @@ -170,20 +177,20 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( st_ivas->nchan_transport = nchan_transport_orig; cldfb_slots = *nSamplesRendered / num_cldfb_bands; - for ( n = 0; n < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) { for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) { - cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[n] ); + cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] ); for ( b = 0; b < num_cldfb_bands; b++ ) { - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + ( 0.5f * Cldfb_RealBuffer[b] ); - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + ( 0.5f * Cldfb_ImagBuffer[b] ); } } diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 1be9e6182943ca9e7efcba741043e5094556c64f..a547d96ac06596135212b49a26ae75c0dd2f3d3a 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" @@ -436,7 +433,11 @@ void ivas_renderer_select( else if ( st_ivas->ivas_format == MC_FORMAT ) { *internal_config = transport_config; +#ifdef FIX_1052_EXT_OUTPUT + if ( st_ivas->mc_mode == MC_MODE_MCT && *internal_config != output_config && output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) +#else if ( st_ivas->mc_mode == MC_MODE_MCT && *internal_config != output_config ) +#endif { if ( output_config != IVAS_AUDIO_CONFIG_FOA && output_config != IVAS_AUDIO_CONFIG_HOA2 && output_config != IVAS_AUDIO_CONFIG_HOA3 ) { @@ -450,7 +451,11 @@ void ivas_renderer_select( else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) { *internal_config = transport_config; +#ifdef FIX_1052_EXT_OUTPUT + if ( *internal_config != output_config && output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) +#else if ( *internal_config != output_config ) +#endif { if ( output_config != IVAS_AUDIO_CONFIG_FOA && output_config != IVAS_AUDIO_CONFIG_HOA2 && output_config != IVAS_AUDIO_CONFIG_HOA3 ) { @@ -475,7 +480,14 @@ void ivas_renderer_select( } else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { +#ifdef FIX_1052_EXT_OUTPUT + if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) + { + *internal_config = output_config; + } +#else *internal_config = output_config; +#endif /* 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..dd3316daae02db91fcfa80bc6c9ea7e9e1f0b17d 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -1203,6 +1203,9 @@ int16_t ivas_qmetadata_dec_sid_decode( float direction_vector[3]; int16_t metadata_sid_bits; /* bits allocated to SID for metadata */ int16_t bits_delta, bits_dir; +#ifdef NONBE_FIX_1052_SBA_EXT + int16_t sba_spar_bitlen; +#endif #ifdef DEBUG_MODE_QMETADATA static FILE *pF = NULL; static FILE *pF_azi = NULL; @@ -1221,7 +1224,12 @@ int16_t ivas_qmetadata_dec_sid_decode( if ( ivas_format == SBA_FORMAT ) { +#ifdef NONBE_FIX_1052_SBA_EXT + 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 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*/ +#endif } else { diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 30779c35de49e3c87b73c9a8dcadafaf65695a40..920af84ff7d61a3ee3a612e451c5977e7f7b4bb5 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -390,6 +390,7 @@ 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 }; +#ifndef FIX_1053_REVERB_RECONFIGURATION /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ @@ -399,146 +400,8 @@ 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..81463cd9b8b99a06e1c1f6aaf25c0907c7719164 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -96,37 +96,12 @@ extern const uint16_t *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; extern const float dirac_dithering_azi_scale[DIRAC_DIFFUSE_LEVELS]; extern const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS]; - +#ifndef FIX_1053_REVERB_RECONFIGURATION /*----------------------------------------------------------------------------------* * 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 diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 1b676b2a1ba4e09426ee207a308d2da3b16150c5..110b45b15ff39221701ad10762f723d445ca9059 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -70,7 +70,11 @@ 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; } +#ifdef NONBE_FIX_ISM_XOVER_BR + else if ( st_ivas->nchan_transport == 2 && st_ivas->ivas_format != SBA_ISM_FORMAT ) +#else else if ( st_ivas->nchan_transport == 2 ) +#endif { for ( n = 0; n < CPE_CHANNELS; n++ ) { @@ -124,6 +128,9 @@ ivas_error ivas_sba_dec_reconfigure( ivas_error error; ISM_MODE ism_mode_old; int16_t granularity_new; +#ifdef NONBE_FIX_ISM_XOVER_BR + int16_t nchan_transport; +#endif ism_mode_old = st_ivas->ism_mode; hDecoderConfig = st_ivas->hDecoderConfig; @@ -143,7 +150,11 @@ ivas_error ivas_sba_dec_reconfigure( if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + if ( ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ) == ISM_SBA_MODE_DISC ) +#else if ( ivas_total_brate >= IVAS_256k ) +#endif { st_ivas->ism_mode = ISM_SBA_MODE_DISC; } @@ -450,6 +461,9 @@ ivas_error ivas_sba_dec_reconfigure( * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ +#ifdef NONBE_FIX_ISM_XOVER_BR + nchan_transport = st_ivas->nchan_transport; +#endif 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 +533,12 @@ ivas_error ivas_sba_dec_reconfigure( return error; } +#ifdef NONBE_FIX_ISM_XOVER_BR + nchan_transport += st_ivas->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; +#else st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; +#endif } else if ( ism_mode_old == ISM_SBA_MODE_DISC && st_ivas->ism_mode == ISM_MODE_NONE ) { @@ -531,25 +550,28 @@ 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 } + +#ifdef NONBE_FIX_ISM_XOVER_BR + nchan_transport = st_ivas->nchan_transport; +#endif nchan_transport_old += st_ivas->nchan_ism; + st_ivas->ism_mode = ISM_MODE_NONE; } else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + nchan_transport = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; + nchan_transport_old += st_ivas->nchan_ism; +#else st_ivas->nCPE += ( st_ivas->nchan_ism + 1 ) >> 1; nCPE_old = st_ivas->nCPE; nchan_transport_old = st_ivas->nchan_transport; nchan_transport_old += st_ivas->nchan_ism; +#endif } } @@ -578,6 +600,7 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } + } #else if ( st_ivas->hDiracDecBin != NULL ) { @@ -585,8 +608,8 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } -#endif } +#endif /*-----------------------------------------------------------------* * CLDFB instances diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 2e0f4ae0eb1b06a1b24d47ae0a3662be960a7024..cb81db28aae362adf39f630db8a2e17b437c2e20 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -354,7 +354,11 @@ ivas_error ivas_spar_dec( /* read DirAC bitstream */ if ( st_ivas->hQMetaData != NULL ) { +#ifdef NONBE_FIX_1052_SBA_EXT + 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 ); +#else 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 ); +#endif } if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -368,7 +372,11 @@ ivas_error ivas_spar_dec( if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) { +#ifdef NONBE_FIX_1052_SBA_EXT + last_bit_pos -= ( SID_FORMAT_NBITS + SBA_PLANAR_BITS + SBA_ORDER_BITS ); +#else last_bit_pos -= SID_FORMAT_NBITS; +#endif } nb_bits_read_orig = *nb_bits_read; last_bit_pos -= nb_bits_read_orig; @@ -403,7 +411,11 @@ ivas_error ivas_spar_dec( if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) { int16_t zero_pad_bits; +#ifdef NONBE_FIX_1052_SBA_EXT + *nb_bits_read += SID_FORMAT_NBITS + SBA_PLANAR_BITS + SBA_ORDER_BITS; +#else *nb_bits_read += SID_FORMAT_NBITS; +#endif 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 +1577,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++ ) diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 5e312dadb504962df39f0158b852f40e2886ba5e..02f3ead6321ea8279128514e537d9430038f3ac3 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2385,6 +2385,9 @@ 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; +#ifdef NONBE_FIX_1052_SBA_EXT + int16_t sba_spar_bitlen; +#endif sid_bits_len = st0->next_bit_pos; pr_min_max[0] = pSpar_md->min_max[0]; @@ -2443,7 +2446,12 @@ static void ivas_parse_parameter_bitstream_dtx( } sid_bits_len = st0->next_bit_pos - sid_bits_len; +#ifdef NONBE_FIX_1052_SBA_EXT + sba_spar_bitlen = ivas_sba_spar_sid_bitlen( num_dmx_per_band[0] ); + zero_pad_bits = sba_spar_bitlen - sid_bits_len; +#else zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; +#endif 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 ac0a802257c6ac251b83cb5310aecb17069d9942..ed4653e1049f9f48d87f1ff93a49ed9a95b6efe1 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -40,6 +40,7 @@ #include "stat_dec.h" #include "ivas_stat_com.h" #include "ivas_stat_rend.h" +#include "isar_stat.h" /*----------------------------------------------------------------------------------* @@ -837,6 +838,36 @@ typedef struct ivas_binaural_rendering_struct } BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * IVAS decoder specific ISAR wrapper structures + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + +} ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; + +typedef struct +{ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + IVAS_AUDIO_CONFIG config; + +} ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA, *ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; + +typedef struct +{ + ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ + SPLIT_REND_WRAPPER splitrend; + ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ + int16_t numTdSamplesPerChannelCached; + +} ISAR_DEC_SPLIT_REND_WRAPPER, *ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE; +#endif /*----------------------------------------------------------------------------------* * MASA decoder structures @@ -968,38 +999,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 *----------------------------------------------------------------------------------*/ @@ -1140,7 +1139,8 @@ typedef struct Decoder_Struct int16_t flag_omasa_brate; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_SPLIT_REND_WRAPPER hSplitBinRend; /* split binuaral rendering handle */ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; #endif /* JBM module */ diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 5bca3fc63bacf4fb214d8094fba87d83471417b5..775960fa3ee1245b17a8982b9db5d7ac9569431a 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -48,10 +48,17 @@ *-----------------------------------------------------------------------*/ /* The SVD is sensitive to changes to the following constants, so please be careful when trying to tune things */ +#ifdef NONBE_FIX_1069_SVD_TUNING +#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 +#else #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 +#endif /*-----------------------------------------------------------------------* diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index aeb8f84303e8ec6dac28f5c3e9ddecfe84829f8c..9f59528a0c12306f1137782b232e6f9ce55042ea 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" @@ -125,6 +127,9 @@ static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType ); static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset ); static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int16_t nZeroSamples ); +static ivas_error isar_set_split_rend_setup( ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, ISAR_SPLIT_REND_BITS_DATA *splitRendBits ); +static ivas_error ivas_create_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); +static void ivas_destroy_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); #endif static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ); @@ -248,6 +253,46 @@ ivas_error IVAS_DEC_Open( return IVAS_ERR_WRONG_PARAMS; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------------* + * isar_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ + +static ivas_error isar_set_split_rend_setup( + ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; +#endif + + if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } + + ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); + + if ( hCombinedOrientationData != NULL ) + { + isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* * init_decoder_config() @@ -304,6 +349,11 @@ void IVAS_DEC_Close( ( *phIvasDec )->hVoIP = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); +#endif + if ( ( *phIvasDec )->st_ivas ) { ivas_destroy_dec( ( *phIvasDec )->st_ivas ); @@ -468,6 +518,17 @@ ivas_error IVAS_DEC_Configure( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* create ISAR handle */ + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); + } + } +#endif + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { hIvasDec->st_ivas->ivas_format = MONO_FORMAT; @@ -548,6 +609,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; } @@ -881,9 +951,9 @@ ivas_error IVAS_DEC_GetSamples( * Binaural split rendering setup *----------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL && ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - ivas_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend, hIvasDec->st_ivas->hCombinedOrientationData ); + isar_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat ); } #endif @@ -929,9 +999,6 @@ ivas_error IVAS_DEC_GetSamples( { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /* :TODO: change nSamplesAsked also if we are in 5ms 0dof split rendering... */ -#endif } { /* check if we need to run the setup function, tc decoding and feeding the renderer */ @@ -1036,11 +1103,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; @@ -1054,13 +1121,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; @@ -1069,9 +1137,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; } @@ -1079,13 +1147,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 ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) == 0 ) { return IVAS_ERR_WRONG_PARAMS; } @@ -1096,7 +1165,15 @@ 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; + } } @@ -1125,7 +1202,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 ) @@ -1150,15 +1235,29 @@ 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, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, +#endif + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + splitRendBits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) { return error; @@ -1184,7 +1283,7 @@ 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; } @@ -1355,7 +1454,7 @@ static ivas_error IVAS_DEC_GetRenderedSamples( uint16_t *nSamplesRendered, /* o : number of samples rendered */ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the renerer pipeline */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, + const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf #else int16_t *pcmBuf @@ -1683,7 +1782,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_VECTOR3 Pos, /* i : listener position */ #ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t subframe_idx, /* i : subframe index */ - const IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ #else const int16_t subframe_idx /* i : subframe index */ #endif @@ -2034,14 +2133,22 @@ static ivas_error copyRendererConfigStruct( mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); #ifdef SPLIT_REND_WITH_HEAD_ROT + /* TODO: This seems wrong. Why set default instead of copying from hRCin? + * Currently seems to work because we only ever copy from a default-initialized handle anyway */ hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; hRCout->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.isar_frame_size_ms = 20; +#endif hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.lc3plus_highres = hRCin->split_rend_config.lc3plus_highres; +#endif #endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -2099,8 +2206,12 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION + ivas_error error; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error error; +#endif #endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) @@ -2140,7 +2251,81 @@ 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 ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* Re-initialize reverb instance if already available */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* 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; + } + } +#else + /* 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 != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hCrendWrapper->hCrend->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* DirAC CLDFB reverberator */ + if ( hIvasDec->st_ivas->hDiracDecBin != NULL && hIvasDec->st_ivas->hDiracDecBin->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hDiracDecBin->hReverb ) ); + if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin->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; + } + } +#endif + /* 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; + } + } +#endif + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); +#ifdef CONF_DISTATT + mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT hRenderConfig->split_rend_config = renderConfig.split_rend_config; @@ -2148,10 +2333,10 @@ ivas_error IVAS_DEC_FeedRenderConfig( /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ if ( hRenderConfig->split_rend_config.dof == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } - if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -2469,7 +2654,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, + const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf, #else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ @@ -3649,35 +3834,37 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( #ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitRendBits() + * IVAS_DEC_GetSplitRendBitstreamHeader() * * *---------------------------------------------------------------------*/ -/*! r: decoder error code */ -ivas_error IVAS_DEC_GetSplitRendBits( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structue */ +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ +#endif + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pLc3plusHighRes +#endif ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL /*|| hIvasDec->st_ivas->hSplitBinRend == NULL */ ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - splitRendBits->bits_buf = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_buf; - splitRendBits->bits_read = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_read; - splitRendBits->bits_written = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_written; - splitRendBits->buf_len = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->buf_len; - splitRendBits->codec = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec; - splitRendBits->pose_correction = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->pose_correction; - splitRendBits->codec_frame_size_ms = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec_frame_size_ms; - - /* 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; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; +#endif return IVAS_ERR_OK; } @@ -3685,10 +3872,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 */ @@ -3697,24 +3883,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++ ) { @@ -3722,8 +3908,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]; } } } @@ -3739,10 +3925,8 @@ ivas_error IVAS_DEC_GetCldfbSamples( return IVAS_ERR_OK; } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * pcm_buffer_offset() * @@ -3769,8 +3953,10 @@ static void *pcm_buffer_offset( } break; default: - return NULL; + break; } + + return NULL; } @@ -3831,4 +4017,117 @@ PCM_RESOLUTION pcm_type_API_to_internal( return pcm_resolution; } + +/*-------------------------------------------------------------------* + * ivas_create_handle_isar() + * + * Initialize IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static ivas_error ivas_create_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out /* o : ISAR split binaural rendering handle */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + + if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + } + + isar_init_split_rend_handles( &hSplitBinRend->splitrend ); + + hSplitBinRend->hMultiBinCldfbData = NULL; + hSplitBinRend->hCldfbDataOut = NULL; + hSplitBinRend->numTdSamplesPerChannelCached = 0; + + *hSplitBinRend_out = hSplitBinRend; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_destroy_handle_isar() + * + * destroy IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static void ivas_destroy_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */ +) +{ + if ( *hSplitBinRend != NULL ) + { + ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); + + if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + { + free( ( *hSplitBinRend )->hCldfbDataOut ); + ( *hSplitBinRend )->hCldfbDataOut = NULL; + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ + +int16_t IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + Decoder_Struct *st_ivas; + int16_t isSplitRend; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + isSplitRend = 0; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + isSplitRend = 1; + } + + return isSplitRend; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_coded_out() + * + * + *---------------------------------------------------------------------*/ + +int16_t IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + Decoder_Struct *st_ivas; + int16_t isSplitCoded; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + isSplitCoded = 0; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + isSplitCoded = 1; + } + + return isSplitCoded; +} #endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 2dccb455256a25ef6f071d0a99d306deac1ba0c7..bafbf36dace0112580f621a01166171d6dccfc98 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -172,15 +172,24 @@ ivas_error IVAS_DEC_GetSamples( ivas_error IVAS_DEC_GetSplitBinauralBitstream( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); /*! r: decoder error code */ -ivas_error IVAS_DEC_GetSplitRendBits( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structure */ +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ +#endif + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pLc3plusHighRes /* o: pointer to LC3plus High-Res setting */ +#endif ); /*! r: decoder error code */ @@ -191,6 +200,13 @@ ivas_error IVAS_DEC_GetCldfbSamples( IVAS_AUDIO_CONFIG *audio_config, /* o : audio configuration */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ ); + +int16_t IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec /* i: IVAS decoder handle */ +); +int16_t IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); #endif /*! r: error code */ @@ -215,7 +231,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_VECTOR3 Pos, /* i : listener position */ #ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t subframe_idx, /* i : subframe index */ - IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ #else const int16_t subframe_idx /* i : subframe index */ #endif @@ -272,7 +288,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, + const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf, #else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index be39e263b904b27eae16ba70a5bba8e0a3c99379..c7768972f61aae109dfc34a4a87cabb59f9f6916 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -446,7 +446,11 @@ ivas_error ivas_corecoder_enc_reconfig( } else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + if ( ( error = mct_enc_reconfigure( st_ivas, nchan_transport_old_real != nchan_transport_real ) ) != IVAS_ERR_OK ) +#else if ( ( error = mct_enc_reconfigure( st_ivas, st_ivas->nchan_transport != nchan_transport_old ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index f971fcbe677a18e739bb31b8173dfbd0f14bd8fc..3fdf6e9f5e3dbabf1e649ada5807907980dd1772 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -600,6 +600,16 @@ ivas_error ivas_cpe_enc( if ( sts[0]->core_brate == SID_2k40 ) { ivas_write_format_sid( ivas_format, hCPE->element_mode, sts[0]->hBstr ); +#ifdef NONBE_FIX_1052_SBA_EXT + 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 ); + } +#endif } /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 3146d8ad9bbd51559c68bb96bee670202cf847c2..cd4dbe6438244f944c8956a3e713ca2b326840df 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -291,7 +291,10 @@ 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 */ +#ifdef NONBE_FIX_1052_SBA_EXT + const int16_t nchan_transport, /* i : number of transport channels */ +#endif + const int16_t hodirac_flag /* i : hodirac flag */ ) { int16_t orig_dirac_bands; @@ -367,7 +370,11 @@ ivas_error ivas_dirac_enc( push_next_indice( hMetaData, 1, 1 ); /* encode SID parameters */ +#ifdef NONBE_FIX_1052_SBA_EXT + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, nchan_transport, SBA_FORMAT ); +#else ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT ); +#endif } 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..0371378d73e0d2e5e621732fc6128260989115c3 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -674,10 +674,14 @@ ivas_error ivas_init_encoder( { st_ivas->ism_mode = ISM_MODE_NONE; +#ifdef NONBE_FIX_ISM_XOVER_BR + st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism ); +#else if ( ivas_total_brate >= IVAS_256k ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; } +#endif if ( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK ) { @@ -732,8 +736,17 @@ ivas_error ivas_init_encoder( else { /* allocate and initialize MCT core coder */ - st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; +#ifdef NONBE_FIX_ISM_XOVER_BR + { + int16_t n_all; + + n_all = st_ivas->nchan_transport + st_ivas->hEncoderConfig->nchan_ism; + st_ivas->nCPE = ( n_all + 1 ) >> 1; + } +#else + st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; +#endif 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..2c5e2bb5b241c43eb3a599250f772aab115276aa 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -420,6 +420,18 @@ ivas_error ivas_masa_encode( { if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MODE_NONE ) { +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + /* 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, nchan_ism - 1, MASA_TRANSP_BITS ); + } + else + { + /* for 3 or 4 objects write already the number of MASA directions */ + push_next_indice( hMetaData, hQMetaData->no_directions - 1, MASA_TRANSP_BITS ); + } +#else /* use the MASA number of transport channels bit to signal if there are 3 or 4 objects */ if ( nchan_ism == 4 ) { @@ -429,6 +441,7 @@ ivas_error ivas_masa_encode( { push_next_indice( hMetaData, 0, MASA_TRANSP_BITS ); } +#endif } else { @@ -440,6 +453,16 @@ ivas_error ivas_masa_encode( if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MODE_NONE ) { +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + if ( nchan_ism >= 3 ) /* if 3 or 4 objects */ + { + push_next_indice( hMetaData, 5 - nchan_ism, MASA_HEADER_BITS ); + } + else + { + push_next_indice( hMetaData, 3, MASA_HEADER_BITS ); + } +#else if ( nchan_ism <= 3 ) { push_next_indice( hMetaData, nchan_ism, MASA_HEADER_BITS ); @@ -448,6 +471,7 @@ ivas_error ivas_masa_encode( { push_next_indice( hMetaData, nchan_ism - 1, MASA_HEADER_BITS ); } +#endif hQMetaData->metadata_max_bits -= MASA_HEADER_BITS; } else @@ -457,10 +481,16 @@ 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; - +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + if ( !( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MODE_NONE && nchan_ism > 2 ) ) + { +#endif + /* write number of directions */ + push_next_indice( hMetaData, hQMetaData->no_directions - 1, 1 ); + hQMetaData->metadata_max_bits -= 1; +#ifdef NONBE_FIX_1074_NOBJ_SIGNAL_OMASA_LBR + } +#endif /* 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 +626,11 @@ ivas_error ivas_masa_encode( free( h_orig_metadata ); +#ifdef NONBE_FIX_1052_SBA_EXT + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, 0, ivas_format ); +#else ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, ivas_format ); +#endif /* 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..38f927b10925938601ee6e68ede3219d3138fb3e 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -182,9 +182,13 @@ 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; +#ifdef NONBE_FIX_ISM_XOVER_BR + int16_t nchan_transport; +#endif if ( ivas_total_brate != hEncoderConfig->last_ivas_total_brate ) { @@ -197,6 +201,9 @@ ivas_error ivas_osba_enc_reconfig( spar_reconfig_flag = 0; old_ism_mode = st_ivas->ism_mode; +#ifdef NONBE_FIX_ISM_XOVER_BR + st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism ); +#else if ( ivas_total_brate >= IVAS_256k ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; @@ -205,9 +212,11 @@ ivas_error ivas_osba_enc_reconfig( { st_ivas->ism_mode = ISM_MODE_NONE; } +#endif 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 +343,40 @@ ivas_error ivas_osba_enc_reconfig( * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ +#ifdef NONBE_FIX_ISM_XOVER_BR + nchan_transport = st_ivas->nchan_transport; +#endif if ( old_ism_mode == ISM_MODE_NONE && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + { + nchan_transport = st_ivas->nchan_transport + st_ivas->hEncoderConfig->nchan_ism; + st_ivas->nCPE = ( nchan_transport + 1 ) >> 1; + } +#else st_ivas->nCPE += ( st_ivas->hEncoderConfig->nchan_ism + 1 ) >> 1; +#endif } else if ( old_ism_mode == ISM_SBA_MODE_DISC && st_ivas->ism_mode == ISM_MODE_NONE ) { + nchan_transport_old += st_ivas->hEncoderConfig->nchan_ism; +#ifdef NONBE_FIX_ISM_XOVER_BR + nchan_transport = st_ivas->nchan_transport; +#endif } else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { +#ifdef NONBE_FIX_ISM_XOVER_BR + 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; +#else 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; +#endif } 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..dc4806ed19e166a18831adbcbe267e2d0f6b5d62 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -955,7 +955,10 @@ 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 */ +#ifdef NONBE_FIX_1052_SBA_EXT + const int16_t nchan_transport, /* i : number of transport channels */ +#endif + const int16_t ivas_format /* i : IVAS format */ ) { int16_t b, m; @@ -968,10 +971,18 @@ 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 */ +#ifdef NONBE_FIX_1052_SBA_EXT + int16_t sba_spar_bitlen; +#endif if ( ivas_format == SBA_FORMAT ) { +#ifdef NONBE_FIX_1052_SBA_EXT + 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 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*/ +#endif } else { @@ -1250,7 +1261,11 @@ void reset_metadata_spatial( assert( hMetaData->ind_list[0].nb_bits == 1 ); #endif hMetaData->ind_list[0].value = 1; +#ifdef NONBE_FIX_1052_SBA_EXT + metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - SBA_PLANAR_BITS - SBA_ORDER_BITS; +#else metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif 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..b8319618111c7af9c584d7de832bd476ffe62c9d 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -224,6 +224,16 @@ ivas_error ivas_sce_enc( if ( st->core_brate == SID_2k40 ) { ivas_write_format_sid( ivas_format, IVAS_SCE, st->hBstr ); +#ifdef NONBE_FIX_1052_SBA_EXT + 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 ); + } +#endif } /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index d3ff38062aa496c10ea462c3b966f7b876a9276e..0a6f44b1d0117f86b41b850793674395999066f8 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,10 +695,18 @@ static ivas_error ivas_spar_enc_process( hodirac_flag = ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ); +#ifdef NONBE_FIX_1052_SBA_EXT + 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; + } +#else 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 ) { return error; } +#endif + /* 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..83ff86b68b17a26f397839e7b9912276bb09b9df 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -1716,6 +1716,9 @@ static void ivas_write_parameter_bitstream_dtx( int16_t idx; float pr_min_max[2]; int16_t zero_pad_bits, sid_bits_len; +#ifdef NONBE_FIX_1052_SBA_EXT + int16_t sba_spar_bitlen; +#endif 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 +1774,12 @@ static void ivas_write_parameter_bitstream_dtx( } sid_bits_len = hMetaData->nb_bits_tot - sid_bits_len; +#ifdef NONBE_FIX_1052_SBA_EXT + sba_spar_bitlen = ivas_sba_spar_sid_bitlen( num_dmx[0] ); + zero_pad_bits = sba_spar_bitlen - sid_bits_len; +#else zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; +#endif assert( zero_pad_bits >= 0 ); if ( num_dmx[0] == 2 ) { 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..cdc0e6c31997f4b6ca690f5b2c8963195f6f7b0a 100644 --- a/lib_rend/ivas_MSPred.c +++ b/lib_isar/isar_MSPred.c @@ -33,9 +33,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 +72,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; diff --git a/lib_rend/ivas_NoiseGen.c b/lib_isar/isar_NoiseGen.c similarity index 98% rename from lib_rend/ivas_NoiseGen.c rename to lib_isar/isar_NoiseGen.c index 846a49a7871bb43321d29d7bb331d229e8a8f0ca..12c227bece5db81152eb58d639f43c408c362910 100644 --- a/lib_rend/ivas_NoiseGen.c +++ b/lib_isar/isar_NoiseGen.c @@ -35,8 +35,7 @@ #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" 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..4b963ab75af3d2e6b365fc1b50e902fe8f71f29b 100644 --- a/lib_rend/ivas_PerceptualModel.c +++ b/lib_isar/isar_PerceptualModel.c @@ -33,10 +33,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 +45,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 +101,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 +165,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 +201,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; diff --git a/lib_rend/ivas_PredDecoder.c b/lib_isar/isar_PredDecoder.c similarity index 74% rename from lib_rend/ivas_PredDecoder.c rename to lib_isar/isar_PredDecoder.c index ce791e93291b12d5f4034fcf111172137040126d..48031a865dbd0e0b58669438f615d1ecf1dab123 100644 --- a/lib_rend/ivas_PredDecoder.c +++ b/lib_isar/isar_PredDecoder.c @@ -35,9 +35,9 @@ #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" /*-------------------------------------------------------------------* @@ -64,6 +64,41 @@ 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 +217,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 +230,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; @@ -206,7 +249,7 @@ void DeletePredictionDecoder( int32_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 +257,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 ); } @@ -229,7 +272,7 @@ int32_t ReadPredictors( } 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 +285,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 +300,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 +337,69 @@ int32_t ReadPredictors( return iBitsRead; } +/* PLC_IMPROVEMENT */ +void SetDecodingPassed( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailed[ch][n] = 0; + } + } +} +int32_t AnyDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingUnresolved[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +void UpdateDecodingFailedStatus( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = psPredictionDecoder->ppiDecodingFailed[ch][n]; + } + } +} + +void UpdateDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + + int32_t iCurrentSubSet = psPredictionDecoder->iSubSetId; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + /* Prediction data always available for current subset */ + psPredictionDecoder->ppiDecodingUnresolved[ch][iCurrentSubSet] = 0; + + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + int32_t iSubSetActive = get_bit( psPredictionDecoder->piPredChanEnable[ch], n ); + if ( iSubSetActive == 0 ) + { + /* Prediction information available inactive subsets (e.g. no Prediction) */ + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 0; + } + } + } +} + /*-------------------------------------------------------------------* * Function ApplyInversePredictors() * 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..676aa917e6f780ee36a861ed2083da3fc1d5fb7e 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_isar/isar_PredEncoder.c @@ -34,10 +34,10 @@ #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" @@ -66,6 +66,14 @@ static void deactivate_bit( ( *state ) &= ( ~( 1 << bit_id ) ); } +void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder ) +{ + if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) + { + psPredictionEncoder->iSubSetId = 0; + } +} + /*-------------------------------------------------------------------* * Function CreatePredictionEncoder() * @@ -92,16 +100,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 +113,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 +269,6 @@ void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ) { int32_t n; - - free( psPredictionEncoder->pfWindow ); - for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { int32_t k; @@ -367,8 +362,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 +412,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 +424,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 +441,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 +461,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 +485,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 ) @@ -520,61 +505,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 +513,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 +523,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 +539,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 +562,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; } } 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..b8cc48bdaafbabbbedac0522e5a90722470b94e7 100644 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ b/lib_isar/isar_RMSEnvGrouping.c @@ -30,16 +30,13 @@ *******************************************************************************************************/ -/* 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 +241,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 +306,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 +395,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 +538,7 @@ static void ComputeGreedyGroups3( } else { - iDone++; // This only catches a problem + iDone++; /* This only catches a problem*/ } } @@ -590,7 +587,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 +665,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, diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h new file mode 100644 index 0000000000000000000000000000000000000000..d93f9ae39f7b0f2fac02a21309086c42eb6273d6 --- /dev/null +++ b/lib_isar/isar_cnst.h @@ -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. + +*******************************************************************************************************/ + +#ifndef ISAR_CNST_H +#define ISAR_CNST_H + +#include +#include "options.h" + +/* clang-format off */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*----------------------------------------------------------------------------------* + * Split Binaural Rendering Constants + *----------------------------------------------------------------------------------*/ + +typedef enum +{ + PCM_INT16, + PCM_FLOAT32, + PCM_NOT_KNOW = 0xffff +} PCM_RESOLUTION; + +typedef enum +{ + ANY_YAW, + PITCH_ONLY, + ANY_ROLL, + PRED_ONLY, + PRED_ROLL_ONLY, + COM_GAIN_ONLY, + LR_GAIN_ONLY +} ISAR_SPLIT_REND_POSE_TYPE; + + +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ + +#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 +#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 +#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 +#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 +#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ + +#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES ) +#define MAX_SPLIT_REND_MD_BANDS 20 +#define MAX_SPLIT_MD_SUBFRAMES 1 +#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +#define COMPLEX_MD_BAND_THRESH_LOW 4 +#define COMPLEX_MD_BAND_THRESH_HIGH 10 +#else +#define COMPLEX_MD_BAND_THRESH_LOW 5 +#endif +#define SPLIT_REND_RO_MD_BAND_THRESH 4 + +#define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4 +#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63 +#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31 +#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 +#define ISAR_SPLIT_REND_D_QUANT_PNTS 15 +#define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f +#define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f + +#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f +#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f +#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS +#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f +#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f + +#define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED31_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED31_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_31QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) + +#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ) + +#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9 +#define ISAR_SPLIT_REND_DOF_BITS 2 +#define ISAR_SPLIT_REND_HQ_MODE_BITS 1 +#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 +#define ISAR_SPLIT_REND_RO_FLAG_BITS 1 + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2 +#endif + +/*----------------------------------------------------------------------------------* + * Split rendering bitrate constants + *----------------------------------------------------------------------------------*/ + +#define SPLIT_REND_256k 256000 +#define SPLIT_REND_320k 320000 +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 + +#endif /*SPLIT_REND_WITH_HEAD_ROT */ + +#endif /*ISAR_CNST_H */ +/* clang-format on */ diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c new file mode 100644 index 0000000000000000000000000000000000000000..7a9010335f2690c40b4931a374575113efcea973 --- /dev/null +++ b/lib_isar/isar_lc3plus_common.c @@ -0,0 +1,89 @@ +/****************************************************************************************************** + + (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" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function ISAR_LC3PLUS_LC3plusErrToIvasErr() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( + const LC3PLUS_Error lc3PlusError ) +{ + switch ( lc3PlusError ) + { + case LC3PLUS_OK: + return IVAS_ERR_OK; + case LC3PLUS_BITRATE_ERROR: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + default: + break; + } + + return IVAS_ERR_INTERNAL; +} +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ) +{ + switch ( lc3PlusRtpError ) + { + case LC3PLUS_RTP_ERR_NO_ERROR: + return IVAS_ERR_OK; + case LC3PLUS_RTP_ERR_NULL_PTR: + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + case LC3PLUS_RTP_ERR_INVALID_PARAMETERS: + return IVAS_ERR_WRONG_PARAMS; + case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED: + return IVAS_ERR_NOT_IMPLEMENTED; + case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM: + return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE: + return IVAS_ERR_INVALID_BUFFER_SIZE; + case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_GENERIC_ERROR: + default: + break; + } + + return IVAS_ERR_UNKNOWN; +} +#endif +#endif diff --git a/lib_rend/ivas_lc3plus_common.h b/lib_isar/isar_lc3plus_common.h similarity index 75% rename from lib_rend/ivas_lc3plus_common.h rename to lib_isar/isar_lc3plus_common.h index 49657d2b2f75c5f8ff8302b0a7961fb297d535c1..13decaf944f66782242f51c8c09bed0b17da9806 100644 --- a/lib_rend/ivas_lc3plus_common.h +++ b/lib_isar/isar_lc3plus_common.h @@ -30,28 +30,43 @@ *******************************************************************************************************/ -#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" +#ifdef SPLIT_REND_WITH_HEAD_ROT #include "lc3.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "isar_lc3plus_payload.h" +#endif /*! common configuration parameters between encoder and decoder */ typedef struct LC3PLUS_CONFIG { /*! frame duration in microseconds [10000, 5000, 2500] */ - 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; +#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS || defined ISAR_BITSTREAM_UPDATE_LC3PLUS + /*! high resolution mode enabled (1) or disabled (0)*/ + int16_t high_res_mode_enabled; +#endif } LC3PLUS_CONFIG; /*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ -ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); -#endif /* IVAS_LC3PLUS_COM_H */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_COM_H */ diff --git a/lib_rend/ivas_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c similarity index 71% rename from lib_rend/ivas_lc3plus_dec.c rename to lib_isar/isar_lc3plus_dec.c index a5a663884a8e16e875548c669d741010959031a3..565f55e8cc5ee90cb679e1789b96684762001732 100644 --- a/lib_rend/ivas_lc3plus_dec.c +++ b/lib_isar/isar_lc3plus_dec.c @@ -34,41 +34,80 @@ #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 +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Open() + * isar_LC3PLUS_AllocateSubframeDecodingMatrix() * * *------------------------------------------------------------------------*/ -ivas_error IVAS_LC3PLUS_DEC_Open( +static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( + int16_t **subframeChannelMatrix ) +{ + for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + free( subframeChannelMatrix[i] ); + } + + free( subframeChannelMatrix ); + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_Open( const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ - IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ ) { LC3PLUS_Error err; int32_t decoder_size; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t i; + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } +#else int16_t lc3plusFrameIdx; int16_t numLC3plusFramesPerIvasFrame; int16_t i; +#endif - if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" ); + } +#else + if ( 0 == config.lc3plus_frame_duration_us ) { return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); } - numLC3plusFramesPerIvasFrame = (int16_t) ( config.ivas_frame_duration_us / config.lc3plus_frame_duration_us ); + numLC3plusFramesPerIvasFrame = (int16_t) ( config.isar_frame_duration_us / config.lc3plus_frame_duration_us ); +#endif ( *handle )->num_decs = 0; @@ -77,15 +116,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 +134,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,89 +156,103 @@ 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" ); } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled ); +#else err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); +#endif if ( LC3PLUS_OK != err ) { - 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 ) + 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" ); } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == 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" ); } +#endif ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE; +#else for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) { ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; } +#endif /* allocate and configure per LC3plus decoder bitstream cache */ - if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( 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" ); } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/; +#else ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; +#endif if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) { - 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" ); } return IVAS_ERR_OK; } - +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() * * *------------------------------------------------------------------------*/ -ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( +ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ) { @@ -219,7 +272,7 @@ ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( { if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) { - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); + isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); } } @@ -229,44 +282,24 @@ ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix() * * *------------------------------------------------------------------------*/ -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 */ +ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) { int16_t numIvasSubFramesPerLC3frame; uint32_t decIdx; int16_t ivasSubframeIdx; - int16_t effectiveIvasSubframeDuration; + int16_t effectiveIsarSubframeDuration; int16_t actual_num_spatial_subframes; 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 == subframeChannelMatrix ) @@ -274,14 +307,14 @@ ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( 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 ) + if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid isar_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; + effectiveIsarSubframeDuration = (int16_t) ( handle->config.isar_frame_duration_us == 20000 ? handle->config.isar_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.isar_frame_duration_us ); + numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIsarSubframeDuration; + actual_num_spatial_subframes = (int16_t) handle->config.isar_frame_duration_us / effectiveIsarSubframeDuration; /* 0.5(0) = 10ms lc3plus, 5ms subframe */ if ( numIvasSubFramesPerLC3frame != 1 ) { @@ -360,16 +393,17 @@ ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( return IVAS_ERR_OK; } +#endif /*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_GetDelay() + * ISAR_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,7 +411,7 @@ 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 ) { @@ -407,13 +441,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 +464,9 @@ void IVAS_LC3PLUS_DEC_Close( if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) { +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); +#endif free( ( *handle )->selective_decoding_states[iDec] ); } @@ -487,7 +523,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 +531,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 +545,20 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( ) { uint32_t iDec; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t config_num_media_times; + int32_t iMediaTime; + int32_t iFtd; + LC3PLUS_RTP_PAYLOAD payload; +#else int32_t iLc3plusFrame; int32_t lc3framesPerIvasFrame; + int32_t bitstreamOffsetPerCoder; + uint8_t *bitstream_in_iter = bitstream_in; +#endif int32_t ivasSampleIndex; int16_t numSamplesPerLC3plusChannel; - int32_t bitstreamOffsetPerCoder; ivas_error err; - uint8_t *bitstream_in_iter = bitstream_in; if ( NULL == handle ) { @@ -538,19 +581,59 @@ 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, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + if ( !badFrameIndicator ) { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + if ( payload.sampling_rate_hz != handle->config.samplerate ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" ); + } + if ( payload.num_channels != handle->config.channels ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" ); + } + if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" ); + } + if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" ); + } + if ( payload.num_media_times != config_num_media_times ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" ); + } } +#endif - lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times ); + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ ) + { + iFtd = iDec + iMediaTime * handle->num_decs; +#else + lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; - numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame ); + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame ); bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; for ( iDec = 0; iDec < handle->num_decs; iDec++ ) { for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) { +#endif if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) { if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) @@ -572,8 +655,14 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( { handle->bitstream_caches[iDec]->bitstream_cache_size = 0; } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + switch ( handle->selective_decoding_states[iDec]->frame_action ) +#else switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) +#endif { +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS case DEC_ACTION_DECODE_AND_DROP: { err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); @@ -584,8 +673,37 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; } +#endif case DEC_ACTION_DECODE_AND_USE: { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( badFrameIndicator ) + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in, bitstream_in_size, &handle->pcm_conversion_buffer, badFrameIndicator ); + } + else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + /* Untested therefore disabled. Would probably only need to call concealment, + * but the LC3plus API requires a non-NULL ptr for this which is not available here */ + } + else + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], payload.ftds[iFtd].frame_data, payload.ftds[iFtd].frame_data_length, &handle->pcm_conversion_buffer, badFrameIndicator ); + } + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; +#else err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); if ( err != IVAS_ERR_OK ) { @@ -599,15 +717,30 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( } handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; break; +#endif } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS case DEC_ACTION_SKIP: { /* log that this instance has skipped a frame and must decode twice once reactivated */ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; break; } +#endif case DEC_ACTION_CACHE: { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length ); + handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; +#else if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); @@ -618,11 +751,18 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( /* log that this instance has skipped a frame and must decode twice once reactivated */ handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; break; +#endif } case DEC_ACTION_NUM_ENUMS: default: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + } /* for each media time */ + /* reset skipping state, must be set by the user before each decode call*/ + handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE; + } /* for each dec/channel */ +#else bitstream_in_iter += bitstreamOffsetPerCoder; } @@ -634,18 +774,19 @@ static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( } } +#endif 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 +808,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 +839,6 @@ 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 73% rename from lib_rend/ivas_lc3plus_dec.h rename to lib_isar/isar_lc3plus_dec.h index ce4d6281045db590f0cca67ebbcc6211a8b2928c..91af70cef2ef3f192883d2c72c462cd3d29fe451 100644 --- a/lib_rend/ivas_lc3plus_dec.h +++ b/lib_isar/isar_lc3plus_dec.h @@ -30,90 +30,106 @@ *******************************************************************************************************/ -#ifndef IVAS_LC3PLUS_DEC_H -#define IVAS_LC3PLUS_DEC_H +#ifndef ISAR_LC3PLUS_DEC_H +#define ISAR_LC3PLUS_DEC_H #include #include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT #include "lc3.h" #include "ivas_error.h" -#include "ivas_lc3plus_common.h" #include "ivas_cnst.h" +#include "isar_lc3plus_common.h" + typedef enum { +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS DEC_ACTION_DECODE_AND_DROP = 0, +#endif DEC_ACTION_DECODE_AND_USE, +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS DEC_ACTION_SKIP, +#endif DEC_ACTION_CACHE, DEC_ACTION_NUM_ENUMS } SelectiveDecAction; -typedef struct 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; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /*! action to execute for the next frame */ + SelectiveDecAction frame_action; +#else /*! if set to 1, decoder will skip decoding for the next frame */ SelectiveDecAction *frame_actions; +#endif /*! if set to 1, decoder will decode the cache before decoding any of current frames */ int16_t shall_decode_cached_frame; -} 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( +ivas_error ISAR_LC3PLUS_DEC_Open( const LC3PLUS_CONFIG config, /* i : decoder configuration */ - IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ + 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 */ ); +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS /*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ +ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ ); +#endif -ivas_error 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( +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ); -void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); +void ISAR_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); +#endif -#endif /* IVAS_LC3PLUS_DEC_H */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_DEC_H */ diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..da2c1d48f047b8ecbe725b6d2e53430598d07f74 --- /dev/null +++ b/lib_isar/isar_lc3plus_enc.c @@ -0,0 +1,686 @@ +/****************************************************************************************************** + + (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" + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, + int32_t per_channel_bitrate ) +{ + if ( config.high_res_mode_enabled ) + { + switch ( config.lc3plus_frame_duration_us ) + { + case 10000: + return min( per_channel_bitrate, 500000 ); + case 5000: + return min( per_channel_bitrate, 600000 ); + case 2500: + return min( per_channel_bitrate, 672000 ); + default: + assert( false && "unreachable" ); + } + } + + switch ( config.samplerate ) + { + case 48000: + case 32000: + return min( per_channel_bitrate, 320000 ); + case 24000: + return min( per_channel_bitrate, 314400 ); + case 16000: + return min( per_channel_bitrate, 221600 ); + case 8000: + return min( per_channel_bitrate, 114400 ); + default: + assert( false && "unreachable" ); + } + + assert( false && "unreachable" ); + return -1; +} +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Open() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ + const uint32_t bitsPerSecond, /* i : bit rate */ + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t num_lc3plus_media_times_per_ivas_frame; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t lc3plus_num_bytes_per_frame; +#endif + bool is_last_media_time, is_last_channel; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_error ivas_err; +#endif +#endif +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bitsPerSecondPerChannel; +#endif + int32_t encoder_size; + LC3PLUS_Error err; + int32_t lfeChans[1]; + int16_t i; + + lfeChans[0] = 0; + + if ( 0U == config.channels ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsPerSecondPerChannel = bitsPerSecond / config.channels; +#endif +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" ); + } + if ( config.isar_frame_duration_us != 20000 && config.isar_frame_duration_us != 10000 && config.isar_frame_duration_us != 5000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" ); + } +#endif + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); + if ( 0 == encoder_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); + } + + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->config = config; + ( *handle )->frame_type_descriptors = NULL; +#endif + + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->num_encs = 0; + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + } + ( *handle )->num_encs = config.channels; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us; + ( *handle )->fdl_request = s_fdl_request; + ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame; + ( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) ); + if ( NULL == ( *handle )->frame_type_descriptors ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" ); + } +#endif + + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans ); +#else + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); +#endif + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); + } + + err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } +#endif + } + + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->config = config; +#endif + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* update FDI fields */ + for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc ) + { + int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */ +#else + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( ( *handle )->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame; +#endif + if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" ); + } + if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY; + ( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL; + + /* The FTDs in the ToC are included in the following order: + * 1) First the FTD for the first channel of the first FDB (oldest frame) + * 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order + * 3) Then the FTD for the first channel of the second FDB + * 4) Then the FTDs for the remaining channels for the second FDB + * 5) Etc. to the last FDB */ + is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime; + is_last_channel = ( *handle )->num_encs - 1 == iEnc; + if ( is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + } + else if ( !is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + } + else + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + } + } + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond ); + if ( ivas_err != IVAS_ERR_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return ivas_err; + } +#endif +#endif + return IVAS_ERR_OK; +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_SetBitrate() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +) +{ + int32_t numLc3plusMediaTimesPerIvasFrame; + int32_t lc3plus_num_bytes_per_frame; + int32_t availableOctetsPerIsarFrame; + int32_t actualOctetsPerFrame; + LC3PLUS_Error err; + int32_t iFtd; + int32_t fdrLength; + int32_t lc3plusPacketRate; + int32_t numSubframes; + int32_t minPayloadOverhead; + int32_t targetLc3PlusBitratePerChannel; + int32_t targetLc3PlusOctetCount; + int32_t lc3plusFdlLength; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + + availableOctetsPerIsarFrame = bitsPerSecond / ( 1000000 / handle->config.isar_frame_duration_us ) / 8; + lc3plusPacketRate = 1000 * 1000 / handle->config.lc3plus_frame_duration_us; + numLc3plusMediaTimesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSubframes = numLc3plusMediaTimesPerIvasFrame * handle->config.channels; + + /* subtract minimum required payload bytes & calculate a first per-channel target bit rate */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &fdrLength, s_fdl_request ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE ); + targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( targetLc3PlusBitratePerChannel <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" ); + } +#endif + targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel ); + targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate; + /* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &lc3plusFdlLength, targetLc3PlusOctetCount ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + if ( lc3plusFdlLength != LC3PLUS_RTP_FDL_MIN_LENGTH ) + { + /* reduce bitrate to allow for the required fdl field */ + targetLc3PlusBitratePerChannel = ( targetLc3PlusOctetCount - ( lc3plusFdlLength - LC3PLUS_RTP_FDL_MIN_LENGTH ) ) / handle->config.channels * 8 * lc3plusPacketRate; + } + + for ( int32_t iCh = 0; iCh < handle->config.channels; iCh++ ) + { + err = lc3plus_enc_set_bitrate( handle->handles[iCh], targetLc3PlusBitratePerChannel ); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + // update FTD settings after bitrate change + for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc ) + { + iFtd = iEnc + iMediaTime * handle->num_encs; + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + handle->frame_type_descriptors[iFtd].frame_data_length = lc3plus_num_bytes_per_frame; + } + } + + // TODO: remove sanity checks? + if ( ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "ISAR_LC3PLUS_ENC_GetOutputBitstreamSize failed\n" ); + } + if ( actualOctetsPerFrame > availableOctetsPerIsarFrame ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Bitrate reduction logic failed\n" ); + } + return IVAS_ERR_OK; +} +#endif + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetOutputBitstreamSize() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of each bitstream frame in bytes */ +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_RTP_ERR rtp_err; + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t iMediaTime; + int32_t ftd_frame_data_length_size, lc3plus_frame_data_length; + int32_t ftd_index; +#else + int32_t bitstreamSizeMultiplier; +#endif + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == bsSize ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( 0 == handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" ); + } + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; +#endif + *bsSize = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t fdl_request_length; + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" ); + } + *bsSize += fdl_request_length; +#endif + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + ftd_index = iEnc + iMediaTime * handle->num_encs; + if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" ); + } + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" ); + } + *bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + *bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length; + *bsSize += ftd_frame_data_length_size; + } + } +#else + *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + bitstreamSizeMultiplier = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + *bsSize *= bitstreamSizeMultiplier; +#endif + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( NULL != ( *handle )->frame_type_descriptors ) + { + free( ( *handle )->frame_type_descriptors ); + } +#endif + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) + { + if ( NULL != ( *handle )->handles[iEnc] ) + { + lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); + free( ( *handle )->handles[iEnc] ); + } + } + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + + free( ( *handle )->handles ); + free( *handle ); + + *handle = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Encode() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **pcm_in, /* i : pointer input samples */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + void *bitstream_out, /* o : pointer to bitstream frame */ + const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t ftdIndex; + LC3PLUS_RTP_ERR rtpErr; + uint32_t num_media_times; +#else + uint32_t lc3framesPerIvasFrame; + uint8_t *bitstream_out_iter = bitstream_out; +#endif + uint32_t numSamplesPerLC3plusChannel; + int32_t ivasSampleIndex; + int32_t num_bytes = 0; + LC3PLUS_Error err; + + push_wmops( "ISAR_LC3PLUS_ENC_Encode" ); + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); + } + if ( NULL == bitstream_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times; + + size_t actual_size; + rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, s_fdl_request, handle->frame_type_descriptors, handle->num_ftds ); + if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } +#else + lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame; +#endif + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ ) +#else + for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) +#endif + { + for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; +#else + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; +#endif + handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ftdIndex = iMediaTime * handle->num_encs + iEnc; +#endif + num_bytes = 0; + push_wmops( "lc3plus_enc16" ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, NULL ); +#else + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); +#endif + pop_wmops(); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); + } + if ( 0 == num_bytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" ); + } +#else + + bitstream_out_iter += num_bytes; +#endif + } + } + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h similarity index 60% rename from lib_rend/ivas_lc3plus_enc.h rename to lib_isar/isar_lc3plus_enc.h index a4ea7c808faf20e857e8666f5ed07c9e81036999..3a2dffe63ab3c7f58401fa7903735a8afc5aeaa4 100644 --- a/lib_rend/ivas_lc3plus_enc.h +++ b/lib_isar/isar_lc3plus_enc.h @@ -30,47 +30,73 @@ *******************************************************************************************************/ -#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" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#include "isar_lc3plus_common.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "isar_lc3plus_payload.h" +#endif /* encoder wrapper */ -typedef struct 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; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_RTP_FTD *frame_type_descriptors; + int32_t num_ftds; + LC3PLUS_RTP_FDL fdl_request; +#endif +} * ISAR_LC3PLUS_ENC_HANDLE; + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : encoder configuration */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const uint32_t initialBitsPerSecond, /* i : initial target bit rate */ +#else + const uint32_t bitsPerSecond, /* i : bit rate */ +#endif + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ +); -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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ ); +#endif -ivas_error 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 */ +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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + void *bitstream_out, /* o : pointer to bitstream frame */ + const int32_t bitstream_out_size /* i : size of the bitstream_out buffer in bytes. Must be equal to ISAR_LC3PLUS_ENC_GetOutputBitstreamSize. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif ); +#endif -#endif /* 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..b240897655ab4da7c58f7ffbc602c9adb0eefff5 --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.c @@ -0,0 +1,823 @@ +/****************************************************************************************************** + + (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" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi ) +{ + if ( NULL == frame_duration_us ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( fdi ) + { + case LC3PLUS_RTP_FTD_FDI_2500_US: + *frame_duration_us = 2500; + break; + case LC3PLUS_RTP_FTD_FDI_5000_US: + *frame_duration_us = 5000; + break; + case LC3PLUS_RTP_FTD_FDI_10000_US: + *frame_duration_us = 10000; + break; + case LC3PLUS_RTP_FTD_FDI_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == sample_rate_hz ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *sample_rate_hz = 8000; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *sample_rate_hz = 16000; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *sample_rate_hz = 24000; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *sample_rate_hz = 32000; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *sample_rate_hz = 44100; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *sample_rate_hz = 96000; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == high_resolution_flag ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *high_resolution_flag = 1; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *high_resolution_flag = 1; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ) +{ + if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX ) + { + *length = 2; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + *length = 3; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + + if ( NULL == dst ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + if ( 1 == frame_data_length_size ) + { + *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 2 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 3 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE ); + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + return fdl; + } + return 0; +} + +static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return true; + } + return false; +} + +static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request ) +{ + /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */ + if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) ) + { + return true; + } + return false; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) ) + { + *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src ) + { + *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 0 ) + { + *frame_data_length_value = *src << 0; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + + /* sanity check */ + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity ) +{ + int32_t frame_data_block_size; + LC3PLUS_RTP_FDL fdl; + LC3PLUS_RTP_ERR err; + if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *num_bytes_read = 0; + receiver_ftd->fc = 0; + receiver_ftd->fdi = 0; + receiver_ftd->bwr = 0; + receiver_ftd->h = 0; + receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK; + receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK ); + receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK ); + receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK ); + p_read++; + *num_bytes_read = 1; + + err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + frame_data_block_size = s_get_size_from_fdl( fdl ); + + receiver_ftd->frame_data_length = frame_data_block_size; + int32_t length_field_size; + err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + *num_bytes_read += length_field_size; + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ) +{ + LC3PLUS_RTP_ERR err; + uint8_t *p_write = serialized_buffer; + uint32_t i; + int32_t bytes_written = 0; + int32_t lc3plus_frame_size_sum; + uint8_t *p_frame_data; + int32_t fdl_request_length; + + if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *packed_buffer_actual_size = 0; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( fdl_request, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + bytes_written += fdl_request_length; + p_write += bytes_written; + + for ( i = 0; i < sender_ftds_num; ++i ) + { + /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + *p_write = 0x00; + *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc; + *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi; + *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr; + *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h; + p_write++; + bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + + int32_t fdl_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + p_write += fdl_length; + bytes_written += fdl_length; + } + + lc3plus_frame_size_sum = 0; + p_frame_data = serialized_buffer + bytes_written; + for ( i = 0; i < sender_ftds_num; ++i ) + { + sender_ftds[i].frame_data = p_frame_data; + p_frame_data += sender_ftds[i].frame_data_length; + lc3plus_frame_size_sum += sender_ftds[i].frame_data_length; + } + *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum; + assert( *packed_buffer_actual_size <= serialized_buffer_capacity ); + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_ftds_parse( + LC3PLUS_RTP_FTD *receiver_ftds, + const int32_t receiver_ftds_num_max, + int16_t *receiver_ftds_num, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t diff; + uint8_t *p_read; + uint32_t ftds_offset_sum = 0; + int16_t i; + LC3PLUS_RTP_ERR error; + int32_t frame_offset_counter; + int32_t size; + + p_read = serialized_buffer; + if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_EMPTY_TOC; + } + if ( receiver_ftds_num_max <= 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + { + int32_t num_bytes_read_sum = 0; + const int32_t min_num_bytes_per_ftd = 2; + int16_t receiver_ftds_index = 0; + bool another_ftd = true; + int32_t num_bytes_read_per_ftd; + + while ( another_ftd ) + { + if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + num_bytes_read_per_ftd = 0; + error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != error ) + { + return error; + } + p_read += num_bytes_read_per_ftd; + num_bytes_read_sum += num_bytes_read_per_ftd; + + if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL ) + { + another_ftd = false; + } + + if ( another_ftd ) + { + if ( receiver_ftds_index >= receiver_ftds_num_max ) + { + return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED; + } + ( receiver_ftds_index )++; + } + } + *receiver_ftds_num = receiver_ftds_index + 1; + } + + /* set frame-data pointers into serialized_buffer */ + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return error; + } + ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size; + } + + frame_offset_counter = 0; + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) ) + { + receiver_ftds[i].frame_data = NULL; + } + else + { + receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter; + frame_offset_counter += receiver_ftds[i].frame_data_length; + } + } + + if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size ) + { + /* parsed content & size n bytes of input buffer do not line up */ + /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */ + diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter ); + if ( diff < 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + /* verify that all bytes are zero */ + p_read += frame_offset_counter; + for ( i = 0; i < diff; ++i ) + { + if ( *p_read != 0 ) + { + /* non-zero byte in padding region */ + return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES; + } + p_read++; + } + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t new_frame_duration_us; + int32_t new_sampling_rate_hz; + int16_t new_high_resolution_flag; + int16_t i = 0; + int16_t channel_id = 0; + int16_t media_time_id = 0; + const int16_t invalid_value = -1; + int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS]; + int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES]; + LC3PLUS_RTP_ERR err; + + if ( NULL == payload || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id ) + { + channels_per_media_time[media_time_id] = invalid_value; + } + media_time_id = 0; + for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id ) + { + media_times_per_channel[channel_id] = invalid_value; + } + channel_id = 0; + + err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + int32_t fdl_request_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( payload->fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + + err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( 0 == payload->num_ftds ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */ + + /* initialize on the first FTD, use this as reference */ + err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + payload->num_channels = 0; + payload->num_media_times = 0; + for ( i = 0; i < payload->num_ftds; ++i ) + { + if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY ) + { + /* not implemented */ + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + + err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->frame_duration_us != new_frame_duration_us ) + { + /* mixed frame durations not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->sampling_rate_hz != new_sampling_rate_hz ) + { + /* mixed sampling frequencies not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + + err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->high_resolution_enabled != new_high_resolution_flag ) + { + /* mixed high resolution mode not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + switch ( payload->ftds[i].fc ) + { + case LC3PLUS_RTP_FTD_FC_LAST_OVERALL: + channels_per_media_time[media_time_id]++; + media_times_per_channel[channel_id]++; + channel_id = 0; + media_time_id = 0; + break; + case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id++; + break; + case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id = 0; + media_time_id++; + break; + case LC3PLUS_RTP_FTD_FC_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + } + + { + int32_t valid_num_media_times_per_channel; + int32_t iCh; + /* check whether all channels exist for each media time */ + if ( media_times_per_channel[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_media_times_per_channel = media_times_per_channel[0]; + for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh ) + { + if ( media_times_per_channel[iCh] == invalid_value ) + { + break; + } + if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + { + /* whether all media times exist for each channel */ + int32_t iMediaTime; + int32_t valid_num_channels_per_media_time; + if ( channels_per_media_time[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_channels_per_media_time = channels_per_media_time[0]; + for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime ) + { + if ( channels_per_media_time[iMediaTime] == invalid_value ) + { + break; + } + if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + + /* convert zero-index to count */ + payload->num_channels = channels_per_media_time[0] + 1; + payload->num_media_times = media_times_per_channel[0] + 1; + + /* verify that all media times have the same number of channels, partial packets are not supported */ + if ( payload->num_ftds != payload->num_channels * payload->num_media_times ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ) +{ + if ( NULL == bwr ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( sampling_rate ) + { + case 8000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_NB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 16000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_WB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 24000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SSWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 32000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 44100: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_FBCD; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 48000: + if ( 0 == high_res_enabled ) + { + *bwr = LC3PLUS_RTP_FTD_BWR_FB; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + else + { + *bwr = LC3PLUS_RTP_FTD_BWR_FBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + case 96000: + if ( 0 == high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_UBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ) +{ + if ( NULL == fdi ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( frame_duration_us ) + { + case 2500: + *fdi = LC3PLUS_RTP_FTD_FDI_2500_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 5000: + *fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 10000: + *fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + +#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h new file mode 100644 index 0000000000000000000000000000000000000000..1e649690ec435fd690e86f57738b3fb399bd2956 --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.h @@ -0,0 +1,216 @@ +/****************************************************************************************************** + + (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" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + +/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format + * for LC3plus as specified in ETSI TS 103 634. */ + +typedef enum LC3PLUS_RTP_ERR +{ + LC3PLUS_RTP_ERR_NO_ERROR, + LC3PLUS_RTP_ERR_NULL_PTR, + LC3PLUS_RTP_ERR_INVALID_PARAMETERS, + LC3PLUS_RTP_ERR_EMPTY_TOC, + LC3PLUS_RTP_ERR_NOT_IMPLEMENTED, + LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE, + LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED, + LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST, + LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES, + LC3PLUS_RTP_ERR_GENERIC_ERROR +} LC3PLUS_RTP_ERR; + +/* + * The content of the FTD is shown in Figure B.6. + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* FC (2 bits): + * Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC + * indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments + * of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent + * FTD (if available). */ +typedef enum LC3PLUS_RTP_FTD_FC +{ + LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */ + LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */ + LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */ + LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */ +} LC3PLUS_RTP_FTD_FC; +#define LC3PLUS_RTP_FTD_FC_MASK 0x03 + +/* FDI (2 bits): + * Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given + * payload type during the session. The FDI also dictates the TSI, needed for deriving the media + * time in case of more than one frame in the payload. */ +typedef enum LC3PLUS_RTP_FTD_FDI +{ + LC3PLUS_RTP_FTD_FDI_2500_US = 0x00, + LC3PLUS_RTP_FTD_FDI_5000_US = 0x04, + LC3PLUS_RTP_FTD_FDI_10000_US = 0x08, + LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C, +} LC3PLUS_RTP_FTD_FDI; +#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ); + +/* BWR (3 bits): + * Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and + * resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is + * defined in Table B.4. The BWR index shall be static for a given payload type during the session. */ +typedef enum LC3PLUS_RTP_FTD_BWR +{ + LC3PLUS_RTP_FTD_BWR_NB = 0x00, + LC3PLUS_RTP_FTD_BWR_WB = 0x10, + LC3PLUS_RTP_FTD_BWR_SSWB = 0x20, + LC3PLUS_RTP_FTD_BWR_SWB = 0x30, + LC3PLUS_RTP_FTD_BWR_FBCD = 0x40, + LC3PLUS_RTP_FTD_BWR_FB = 0x50, + LC3PLUS_RTP_FTD_BWR_FBHR = 0x60, + LC3PLUS_RTP_FTD_BWR_UBHR = 0x70, +} LC3PLUS_RTP_FTD_BWR; +#define LC3PLUS_RTP_FTD_BWR_MASK 0x70 +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ); + +/* H (1 bit): + * Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame + * (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */ +typedef enum LC3PLUS_RTP_FTD_H +{ + LC3PLUS_RTP_FTD_H_PRIMARY = 0x00, + LC3PLUS_RTP_FTD_H_SECONDARY = 0x80, +} LC3PLUS_RTP_FTD_H; +#define LC3PLUS_RTP_FTD_H_MASK 0x80 + +typedef enum LC3PLUS_RTP_FDL +{ + LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0, + LC3PLUS_RTP_FDL_SPEECH_BAD = 1, + LC3PLUS_RTP_FDL_SPEECH_SID = 2, + LC3PLUS_RTP_FDL_RESERVED_MIN = 3, + LC3PLUS_RTP_FDL_RESERVED_MAX = 19, + LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20, + LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254, + LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255, + LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509, + LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510, + LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765 +} LC3PLUS_RTP_FDL; +/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */ +#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF + +typedef struct LC3PLUS_RTP_FTD +{ + LC3PLUS_RTP_FTD_FC fc; + LC3PLUS_RTP_FTD_FDI fdi; + LC3PLUS_RTP_FTD_BWR bwr; + LC3PLUS_RTP_FTD_H h; + uint8_t *frame_data; + LC3PLUS_RTP_FDL frame_data_length; +} LC3PLUS_RTP_FTD; +#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1 +#define LC3PLUS_RTP_FDL_MIN_LENGTH 1 +#define LC3PLUS_RTP_FTD_MIN_SIZE ( LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + LC3PLUS_RTP_FDL_MIN_LENGTH ) + +/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer + * @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to + * @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes + * @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity) + * @param[in] fdl_request frame data length request + * @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in + * the packed_buffer (so it can subsequently be used as input for the LC3plus encode call) + * @param[in] sender_ftds_num number of sender_ftds + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ); + +/*! Get size of the frame data length field for a certain frame data length value in bytes. + * @param[out] length size of the frame data length field in bytes [1,2,3] + * @param[in] frameDataLengthValue frame data length value + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ); + +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16 +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */ +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES + +typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG +{ + /* frame duration in us shared among all FTDs */ + int32_t frame_duration_us; + /* high resolution flag shared among all FTDs */ + int16_t high_resolution_enabled; + /* sampling frequency shared among all FTDs */ + int32_t sampling_rate_hz; + /* number of individual channels in the payload */ + int16_t num_channels; + /* number of individual media times in the payload */ + int16_t num_media_times; + /* frame data length request */ + LC3PLUS_RTP_FDL fdl_request; + /* FTD data with pointer to raw frame data */ + LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS]; + /* actual number of ftds */ + int16_t num_ftds; +} LC3PLUS_RTP_PAYLOAD; + +/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct + * @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer. + * @param serialized_buffer pointer to the start of the serialized input buffer + * @param serialized_buffer_size size of the serialized input buffer in bytes + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ); + +#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */ +#endif /* #ifdef SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_PAYLOAD_H */ diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c similarity index 77% rename from lib_rend/ivas_lcld_decoder.c rename to lib_isar/isar_lcld_decoder.c index b98b4f4e00ef2cae0f2328217b857d5e0fc11e30..f8d13cf7ff403644485db762d8a734af5e4e9279 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_isar/isar_lcld_decoder.c @@ -33,11 +33,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" @@ -93,6 +93,7 @@ struct LCLD_DECODER int32_t ***pppiAlloc; int32_t iAllocOffset; + int32_t iRealOnlyOut; int32_t ***pppiLCLDSignReal; int32_t ***pppiLCLDSignImag; @@ -105,14 +106,14 @@ struct LCLD_DECODER NoiseGen *psNoiseGen; }; -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ); -static TableNode *CreateTableList( int32_t iReadLength ); +static void 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 *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated ); +static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables ); +static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated ); -static TableNode *CreateTableList( int32_t iReadLength ) +static TableNode *CreateTableList( const int32_t iReadLength ) { int32_t n; int32_t iMaxTables; @@ -172,7 +173,7 @@ static void DeleteTableList( TableList *ptable_list, int32_t iTables ) free( ptable_list ); } } -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,7 +194,7 @@ 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; @@ -202,7 +203,7 @@ static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *pt iMaxTables = 1 << iReadLength; psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = - malloc( iTablesCreated * iMaxTables * sizeof( uint32_t * ) ); + malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) ); poNode = ptable_list->poOrderedTop; for ( j = 0; j < iTablesCreated; j++ ) @@ -222,7 +223,7 @@ static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *pt poNode = poNode->poOrderedNext; } } -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; @@ -257,7 +258,7 @@ static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t i } } -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; @@ -345,7 +346,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 +362,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; @@ -702,23 +711,108 @@ 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 ReadAllocInformation( int32_t *piAllocOffset, 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, 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] ); - +ReadLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiDecodingUnresolved, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiSMR, const int32_t iAllocOffset, int32_t ***pppiAlloc ); +void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailed[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = 1; + } + } +} + +int32_t AnyDecodingFailedPrev( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailedPrev[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +int32_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailed[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +int32_t **GetDecodingFailedStatus( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed; +} + +int16_t GetNumSubSets( LCLDDecoder *psLCLDDecoder ) +{ + return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets; +} + +int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev; +} + +static void UnpackReal( + const int32_t iChannels, + const int32_t iNumBlocks, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t ch, b, n; + for ( ch = 0; ch < iChannels; ch++ ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + int32_t iRealBlock = iNumBlocks - 1; + for ( n = iNumBlocks / 2 - 1; n >= 0; n-- ) + { + pppfReal[ch][iRealBlock][b] = pppfImag[ch][n][b] * 2.0f; + pppfReal[ch][iRealBlock - 1][b] = pppfReal[ch][n][b] * 2.0f; + pppfImag[ch][iRealBlock][b] = 0.0f; + pppfImag[ch][iRealBlock - 1][b] = 0.0f; + iRealBlock -= 2; + } + } + } +} /*------------------------------------------------------------------------------------------* * Function DecodeLCLDFrame() @@ -728,7 +822,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, float ***pppfLCLDReal, float ***pppfLCLDImag ) { @@ -742,6 +836,8 @@ 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 ); @@ -776,20 +872,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 +942,15 @@ int32_t DecodeLCLDFrame( pppfLCLDReal, pppfLCLDImag ); } - return 0; + if ( psLCLDDecoder->iRealOnlyOut == 1 ) + { + UnpackReal( psLCLDDecoder->iChannels, + psLCLDDecoder->iNumBlocks * 2, + pppfLCLDReal, + pppfLCLDImag ); + } + + return AnyDecodingUnresolved( psLCLDDecoder->psPredictionDecoder ); } @@ -1051,7 +1158,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; @@ -1077,12 +1184,12 @@ 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 +1202,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 +1231,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 +1241,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 +1255,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 +1263,10 @@ 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 +1284,10 @@ 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++ ) @@ -1221,14 +1328,14 @@ static int32_t ReadGroupInformation( 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 +1346,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 +1377,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 +1404,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 +1426,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 +1439,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 +1452,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 +1478,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 +1488,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,12 +1512,12 @@ 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; @@ -1418,140 +1525,163 @@ static int32_t ReadAllocInformation( } 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; + + b = c_aiBandIdPerLcldBand[iFBOffset]; + + iAlloc = pppiAlloc[ch][n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; - if ( piPredEnable[iFBOffset] == 1 ) + 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++; } } return iBitsRead; } - static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, 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..3d110a5a3043d467e640c0cb44396ba064f5849f 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_isar/isar_lcld_encoder.c @@ -35,10 +35,8 @@ #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 +60,7 @@ struct LCLD_ENCODER int32_t piLRPhaseDiffs[MAX_BANDS]; int32_t iAllowSidePred; + int32_t iRealOnlyOut; RMSEnvelopeGrouping *psRMSEnvelopeGrouping; @@ -136,6 +135,28 @@ static float UnQuantize( return fVal; } +static void PackReal( + const int32_t iChannels, + const int32_t iNumBlocks, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t ch, b, n; + for ( ch = 0; ch < iChannels; ch++ ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + int32_t iRealBlock = 0; + for ( n = 0; n < iNumBlocks; n += 2 ) + { + pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b]; + pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b]; + iRealBlock++; + } + } + } +} + /*------------------------------------------------------------------------------------------* * Function CreateLCLDEncoder() * @@ -149,14 +170,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,19 +189,24 @@ 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 ) { @@ -192,10 +219,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" ) ); @@ -505,23 +531,23 @@ void DeleteLCLDEncoder( * Local function declarations *------------------------------------------------------------------------------------------*/ -static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t *piMSMode, int32_t *piLRPhaseDiff, int32_t *piMSPredCoef, const int32_t iAllowSidePred, 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, 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 ); @@ -537,15 +563,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 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,11 +591,12 @@ 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 */ } } @@ -699,36 +733,26 @@ int32_t EncodeLCLDFrame( 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 ); - } + 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; -} - + UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder ); -/*------------------------------------------------------------------------------------------* - * Function GetNumGroups() - * - * - *------------------------------------------------------------------------------------------*/ - -int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder ) -{ - return psLCLDEncoder->piNumGroups[0]; + return 0; } @@ -763,6 +787,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 +795,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 +865,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 +919,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 +981,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 ); @@ -1013,7 +1059,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] ); @@ -1120,9 +1166,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, @@ -1314,12 +1360,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; @@ -1333,7 +1379,7 @@ static int32_t WriteMSInformation( const int32_t *piLRPhaseDiff, const int32_t *piMSPredCoef, int32_t iNumMSPredBands, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits ) { int32_t iBitsWritten; int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); @@ -1341,12 +1387,12 @@ static int32_t WriteMSInformation( 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 +1401,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 +1422,17 @@ 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 +1447,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 +1482,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 +1517,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 +1536,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 +1558,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 +1574,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 +1585,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 +1599,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,137 +1610,142 @@ 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; } - 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++; } } return iBitsWritten; } - static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, @@ -1785,7 +1836,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,16 +1879,14 @@ 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\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); + printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed); + */ return iBitsUsed; } 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..b685ad284be6761182256f1b6c1ab99fd05fdfaf 100644 --- a/lib_rend/ivas_lcld_prot.h +++ b/lib_isar/isar_lcld_prot.h @@ -30,13 +30,13 @@ *******************************************************************************************************/ -#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 +49,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 +63,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 +72,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 +81,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 +95,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 +237,6 @@ typedef struct PREDICTION_ENCODER float **ppfPredStateImagTmp; float **ppfInpPrevReal; /* channels, bands */ float **ppfInpPrevImag; - - float *pfWindow; float pfRxxReal[2]; float pfRxxImag[2]; @@ -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; @@ -319,9 +316,43 @@ void DeletePredictionDecoder( int32_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); + +int32_t AnyDecodingFailedPrev( + LCLDDecoder *psLCLDDecoder); + +int32_t AnyDecodingFailed( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedStatus( + LCLDDecoder *psLCLDDecoder); + +int16_t GetNumSubSets( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedPrevStatus( + LCLDDecoder *psLCLDDecoder); + +void SetDecodingPassed( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingFailedStatus( + PredictionDecoder *psPredictionDecoder); + +int32_t AnyDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + void ApplyInversePredictors( PredictionDecoder *psPredictionDecoder, float ***pppfReal, diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h new file mode 100644 index 0000000000000000000000000000000000000000..7431b7bc950cdca71949191dd86f81f00a177c01 --- /dev/null +++ b/lib_isar/isar_prot.h @@ -0,0 +1,401 @@ +/****************************************************************************************************** + + (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" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include +#include "options.h" +#include "ivas_error.h" +#include "lib_isar_post_rend.h" + +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + const int32_t output_Fs +#endif +); + +ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size +#else + const int16_t num_subframes +#endif +); + +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ); + +void lc3plusTimeAlignCldfbPoseCorr( + SPLIT_REND_WRAPPER *hSplitBin, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ); + +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int32_t available_bits, +#else + const int32_t SplitRendBitRate, +#endif + float *in[] ); + +int32_t ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t bits ); + +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t val, + const int32_t bits ); + +ivas_error isar_splitBinLCLDEncOpen( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate, + const int16_t iNumBlocks, + const int16_t iNumIterations ); + +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, + const int16_t iNumSubSets ); + +void isar_splitBinRendPLCClose( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC ); + +ivas_error isar_splitBinLCLDDecOpen( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const int32_t iSampleRate, + const int16_t iChannels, + const int16_t iNumBlocks, + const int16_t iNumIterations ); + +void isar_splitBinLCLDDecClose( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ); + +void isar_splitBinRendPLCsaveState( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ); + +void isar_splitBinRendPLC_xf( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations, + int32_t **ppiDecodingFailed, + int32_t **ppiDecodingFailedPrev ); + +void isar_splitBinRendPLC( + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations, + int32_t **ppiDecodingFailed ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void isar_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const char *filename ); +#endif + +void isar_splitBinLCLDDecProcess( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t bfi ); + +void set_fix_rotation_mat( + float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_splitBinLCLDEncClose( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ); + +void isar_splitBinLCLDEncProcess( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int32_t available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits ); + +void set_pose_types( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_split_rend_init_huff_cfg( + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); + +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ); + +void isar_splitBinPostRendClose( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); + +void isar_SplitRenderer_getdiagdiff( + int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const int16_t sign, + const int16_t min_val, + const int16_t max_val ); + +void isar_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS], +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const int16_t ro_flag, +#endif + int16_t *num_quant_strats +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + , + int16_t *num_complex_bands +#endif +); + +void isar_splitBinPostRendMdDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#else + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#endif +); + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); + +void isar_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ); + +void isar_rend_CldfbSplitPostRendProcess( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionPost, + float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], + float output[][L_FRAME48k], + const int16_t cldfb_in_flag ); + +void isar_rend_CldfbSplitPreRendProcess( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot, + const int16_t ro_md_flag ); + +ivas_error isar_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t isar_frame_size_ms, +#endif + const int16_t codec_frame_size_ms, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int16_t max_bands, + float *in[], + const int16_t low_res_pre_rend_rot, + const int16_t pcm_out_flag, + const int16_t ro_md_flag ); + +void isar_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_renderSplitGetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ); + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +int16_t isar_renderSplitGetRot_axisNumBits( + const int16_t dof ); + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const int16_t dof, + const int16_t code ); + +int16_t isar_renderSplitGetCodeFromRot_axis( + const int16_t dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + int16_t *num_bits ); +#endif + +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ); + +void isar_set_split_rend_ht_setup( + SPLIT_REND_WRAPPER *hSplitrend, + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms ); +#endif + +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int32_t nChannels, + const int32_t codecFrameDurationUs ); +#endif + +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int16_t pcm_out_flag ); + +int32_t isar_get_lcld_bitrate( + const int32_t SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +int8_t isar_get_lc3plus_bitrate_id( + const int32_t SplitRendBitRate ); +#endif + +int32_t isar_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, + const int16_t pcm_out_flag ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error isar_framesize_to_ms( + const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ + int16_t *ms /* o : frame size in ms */ +); +#endif + +ivas_error isar_split_rend_choose_default_codec( + ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ +#endif + int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t num_subframes /* i : number of subframes */ +); + +void ISAR_SPLIT_REND_BITStream_init( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t buf_len_bytes, + uint8_t *pbuf ); + +void isar_split_rend_huffman_dec_init_min_max_len( + isar_split_rend_huffman_cfg_t *p_huff_cfg ); + +int16_t wrap_a( + int16_t val, + const int16_t min_val, + const int16_t max_val ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +int32_t isar_get_lc3plus_size_from_id( + const int8_t SplitRendBitRateId, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms ); +#endif + +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +int32_t get_bit( + const int32_t state, + const int32_t bit_id ); + +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const IVAS_AUDIO_CONFIG config ); + +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ); + +#endif + +/* clang-format on */ + +#endif /* ISAR_PROT_H */ diff --git a/lib_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..7143c81349b475f49274e298494f8f35d4524daa 100644 --- a/lib_rend/ivas_lcld_rom_tables.c +++ b/lib_isar/isar_rom_lcld_tables.c @@ -30,15 +30,22 @@ *******************************************************************************************************/ -#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 */ +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 +77,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 +10940,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, 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..cfad1b7fc390ad3f7d366e0e8feea92c8f8f4d10 100644 --- a/lib_rend/ivas_lcld_rom_tables.h +++ b/lib_isar/isar_rom_lcld_tables.h @@ -30,15 +30,16 @@ *******************************************************************************************************/ -#ifndef _IVAS_TABLES_H_ -#define _IVAS_TABLES_H_ +#ifndef ISAR_ROM_LCLD_TABLES_H +#define ISAR_ROM_LCLD_TABLES_H #include #include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT #ifndef M_PI -#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI +#define M_PI 3.14159265358979323846264338327950288f #endif @@ -47,10 +48,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 +93,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]; @@ -190,30 +190,8 @@ extern const uint16_t c_aauiLCLDHuffEnc62[153][2]; extern const uint16_t c_aauiLCLDHuffEnc63[181][2]; extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2]; extern const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE]; - -#ifdef USE_DEMOD_TABLES -extern const int32_t c_aaiHuffDemod1[16][2]; -extern const int32_t c_aaiHuffDemod2[16][2]; -extern const int32_t c_aaiHuffDemod3[25][2]; -extern const int32_t c_aaiHuffDemod4[36][2]; -extern const int32_t c_aaiHuffDemod5[36][2]; -extern const int32_t c_aaiHuffDemod6[49][2]; -extern const int32_t c_aaiHuffDemod7[64][2]; -extern const int32_t c_aaiHuffDemod8[81][2]; -extern const int32_t c_aaiHuffDemod9[100][2]; -extern const int32_t c_aaiHuffDemod10[169][2]; -extern const int32_t c_aaiHuffDemod11[196][2]; -extern const int32_t c_aaiHuffDemod12[289][2]; -extern const int32_t c_aaiHuffDemod13[324][2]; -extern const int32_t c_aaiHuffDemod14[400][2]; -extern const int32_t c_aaiHuffDemod15[576][2]; -extern const int32_t c_aaiHuffDemod16[729][2]; -extern const int32_t c_aaiHuffDemod17[729][2]; -extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2]; -#endif - extern const uint32_t c_aaiRMSEnvHuffEnc[64][2]; extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE]; +#endif /*SPLIT_REND_WITH_HEAD_ROT*/ - -#endif /* _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..f73a2526b8e4bab4ed39989245df003253fe7e7c --- /dev/null +++ b/lib_isar/isar_rom_post_rend.c @@ -0,0 +1,182 @@ +/****************************************************************************************************** + + (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 */ + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +/* rotations in this array are relative to ref rotation */ +const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60 +}; + +const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + {0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12}, + {6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61}, + {12,7,125},{13,8,254},{14,8,255} +}; + +const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_63QUANT_PNTS][3] = +{ + {-31,11,2040}, + {-30,11,2041}, + {-29,11,2042}, + {-28,11,2043}, + {-27,10,1012}, + {-26,10,1013}, + {-25,10,1014}, + {-24,10,1015}, + {-23,9,498}, + {-22,9,499}, + {-21,9,500}, + {-20,9,501}, + {-19,8,242}, + {-18,8,243}, + {-17,8,244}, + {-16,8,245}, + {-15,7,112}, + {-14,7,113}, + {-13,7,114}, + {-12,7,115}, + {-11,6,48}, + {-10,6,49}, + {-9,6,50}, + {-8,6,51}, + {-7,5,16}, + {-6,5,17}, + {-5,5,18}, + {-4,5,19}, + {-3,4,2}, + {-2,4,3}, + {-1,4,4}, + {0,3,0}, + {1,4,5}, + {2,4,6}, + {3,4,7}, + {4,5,20}, + {5,5,21}, + {6,5,22}, + {7,5,23}, + {8,6,52}, + {9,6,53}, + {10,6,54}, + {11,6,55}, + {12,7,116}, + {13,7,117}, + {14,7,118}, + {15,7,119}, + {16,7,120}, + {17,8,246}, + {18,8,247}, + {19,8,248}, + {20,9,502}, + {21,9,503}, + {22,9,504}, + {23,9,505}, + {24,10,1016}, + {25,10,1017}, + {26,10,1018}, + {27,10,1019}, + {28,11,2044}, + {29,11,2045}, + {30,11,2046}, + {31,11,2047}, +}; + +const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3] = +{ + {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, + {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, + {14,10,1022},{15,10,1023}, +}; + +const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3] = +{ + {-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, + {-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, +{14,10,1022},{15,10,1023}, +}; + +#endif + + +/* clang-format on */ diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..043ba5b2138a9b24af9ade5e5572a11dae30a946 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.h @@ -0,0 +1,69 @@ +/****************************************************************************************************** + + (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" + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +extern const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float isar_split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float isar_split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float isar_split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; +extern const float isar_split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; + +extern const float isar_split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float isar_split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float isar_split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; + +extern const float ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; +extern const int16_t isar_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; +extern const int32_t isar_split_rend_huff_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_pred63_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_pred31_consts[ISAR_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_roll_pred_consts[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_p_d_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t isar_split_rend_huff_p_d_diff_consts[ISAR_SPLIT_REND_D_QUANT_PNTS][3]; +#endif + +#endif diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c similarity index 80% rename from lib_rend/ivas_splitRend_lcld_dec.c rename to lib_isar/isar_splitRend_lcld_dec.c index 9493d076af79417888b4e7ec4daef90abe10b43e..95362d50ed49e18034333606018a14a02796a192 100644 --- a/lib_rend/ivas_splitRend_lcld_dec.c +++ b/lib_isar/isar_splitRend_lcld_dec.c @@ -33,7 +33,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 +43,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, 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 +68,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 +107,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 +121,13 @@ 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 ) { 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,21 @@ 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, +void isar_splitBinLCLDDecProcess( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + ISAR_SPLIT_REND_BITS_HANDLE pBits, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t bfi ) { int16_t k, n; int16_t itr; - push_wmops( "ivas_splitBinLCLDDecProcess" ); + push_wmops( "isar_splitBinLCLDDecProcess" ); assert( hSplitBinLCLDDec != NULL ); assert( Cldfb_Out_Real != NULL ); @@ -224,21 +224,32 @@ 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(); diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c similarity index 92% rename from lib_rend/ivas_splitRend_lcld_enc.c rename to lib_isar/isar_splitRend_lcld_enc.c index 6903989dd158a5b880c30fdd8300e3fa319b2feb..ebeaacab9ca0f9cfb69e8307922c0363dd9911fb 100644 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ b/lib_isar/isar_splitRend_lcld_enc.c @@ -33,7 +33,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 +42,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, 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 +66,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 +115,13 @@ 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 ) { if ( ( *hSplitBinLCLDEnc ) != NULL ) { @@ -151,20 +151,20 @@ 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, 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 ) { 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 ); 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..e781676d5f366658dfa5624a3d91a1f4adba1fbb 100644 --- a/lib_rend/ivas_splitRendererPLC.c +++ b/lib_isar/isar_splitRendererPLC.c @@ -37,7 +37,7 @@ #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 +48,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 +66,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 +164,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 +179,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 +198,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 +215,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 +233,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 +280,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 +290,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 +299,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 +312,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, + 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 +342,13 @@ 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 ) { 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,47 +462,43 @@ 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 } } diff --git a/lib_rend/ivas_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c similarity index 77% rename from lib_rend/ivas_splitRendererPost.c rename to lib_isar/isar_splitRendererPost.c index 002229d8b8e60b584d498f59b4f0c7ff99808134..6ea2d2539f450e4fefa0aef920ecc18c29abbf43 100644 --- a/lib_rend/ivas_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -39,30 +39,41 @@ #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, /* 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 ); + /*------------------------------------------------------------------------- - * ivas_splitBinPostRendOpen() + * isar_splitBinPostRendOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinPostRendOpen( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int32_t output_Fs ) { - BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; + 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 +120,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 +128,13 @@ 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 ) { int16_t ch; @@ -165,14 +176,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, const int16_t *idx_trav_list ) { int32_t i, ind, code, num_bits, code_b, num_bits_read; @@ -191,7 +202,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 ) @@ -211,15 +222,15 @@ static int16_t ivas_split_rend_huffman_decode_opt( } /*-----------------------------------------------------------------------------------------* - * 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,7 +242,7 @@ static void ivas_split_rend_unquant_md( float quantstep; quantstep = pred_quant_step; - +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) @@ -240,8 +251,20 @@ static void ivas_split_rend_unquant_md( hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; } } +#endif if ( real_only ) { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + ( ( ch1 == ch2 ) ? 1.0f : 0.0f ); + } + } +#endif + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) @@ -252,6 +275,17 @@ static void ivas_split_rend_unquant_md( } else { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * quantstep; + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; + } + } +#endif + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) @@ -263,18 +297,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,14 +320,14 @@ 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, +static void isar_splitBinPostRendMdBase2Dec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int16_t num_subframes, const int16_t pred_real_bands_yaw, @@ -309,12 +343,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,6 +371,7 @@ static void ivas_splitBinPostRendMdBase2Dec( { if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; @@ -344,7 +379,7 @@ static void ivas_splitBinPostRendMdBase2Dec( { 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; } } @@ -356,15 +391,49 @@ static void ivas_splitBinPostRendMdBase2Dec( { 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; } } } +#else + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_idx; + } + hMd->pred_mat_re_idx[0][1] = 0; + hMd->pred_mat_re_idx[1][0] = 0; + } +#endif for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) 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,14 +442,15 @@ 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 { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; @@ -388,7 +458,7 @@ static void ivas_splitBinPostRendMdBase2Dec( { 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; } } @@ -400,11 +470,45 @@ static void ivas_splitBinPostRendMdBase2Dec( { 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; } } } +#else + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); + hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx; + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); + hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx; + } + } + } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, pred_roll_code_len ); + hMd->pred_mat_re_idx[ch1][ch1] = code + min_pred_roll_idx; + } + hMd->pred_mat_re_idx[0][1] = 0; + hMd->pred_mat_re_idx[1][0] = 0; + } +#endif } } } @@ -414,14 +518,14 @@ 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, +static void isar_splitBinPostRendMdHuffDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int16_t num_subframes, const int16_t pred_real_bands_yaw, @@ -437,12 +541,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 +558,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,6 +566,7 @@ static void ivas_splitBinPostRendMdHuffDec( { if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; @@ -469,11 +574,10 @@ 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[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 ); + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); } for ( b = 0; b < pred_imag_bands_yaw; b++ ) { @@ -482,17 +586,48 @@ 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[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 ); } +#else + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + sym_adj_idx[ch1][ch1] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred[pred_cb_idx], pBits, pHuff_cfg->pred_idx_trav[pred_cb_idx] ); + } + sym_adj_idx[1][0] = 0; + sym_adj_idx[0][1] = 0; + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_idx, max_pred_idx ); + } +#endif for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd_idx = 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,14 +635,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 { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; @@ -516,25 +651,59 @@ 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 ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); + } + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); } } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_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 ); } +#else for ( b = 0; b < pred_imag_bands_roll; b++ ) { hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = isar_split_rend_huffman_decode_opt( &pHuff_cfg->pred_roll, pBits, pHuff_cfg->pred_roll_idx_trav ); + } + } + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - sym_adj_idx[ch1][ch2] = 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 ); + } +#endif } } } @@ -544,14 +713,14 @@ 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, +void isar_splitBinPostRendMdDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , @@ -560,28 +729,50 @@ 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 pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t num_quant_strats; +#else int16_t num_complex_bands, num_quant_strats; +#endif int32_t quant_strat_bits, is_huff_coding, quant_strat; - int16_t pred_quant_pnts_yaw[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; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t ro_md_flag, num_bits, axis_code; +#endif hBinHrSplitPostRend->low_Res = 1; - split_rend_config.dof = (int16_t) 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 ); - ivas_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof ); + if ( num_bits > 0 ) + { + axis_code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, (int32_t) num_bits ); + } + else + { + axis_code = 0; + } + rot_axis = isar_renderSplitGetRot_axisFromCode( split_rend_config.dof, axis_code ); + ro_md_flag = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_RO_FLAG_BITS ); +#else + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_ROT_AXIS_BITS ); +#endif + + isar_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); set_pose_types( hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); @@ -593,20 +784,35 @@ 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( +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_split_rend_get_quant_params( + MAX_SPLIT_REND_MD_BANDS, + pred_real_bands_yaw, + pred_imag_bands_yaw, + pred_quant_pnts_yaw, + pred_quantstep_yaw, + pred_1byquantstep_yaw, + d_bands_yaw, + bands_pitch, + pred_real_bands_roll, + pred_imag_bands_roll, + ro_md_flag, + &num_quant_strats ); +#else + isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, @@ -619,14 +825,15 @@ void ivas_splitBinPostRendMdDec( pred_imag_bands_roll, &num_quant_strats, &num_complex_bands ); +#endif 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 +847,7 @@ void ivas_splitBinPostRendMdDec( } else { - ivas_splitBinPostRendMdHuffDec( + isar_splitBinPostRendMdHuffDec( pBits, hBinHrSplitPostRend, pMultiBinPoseData, num_subframes, @@ -765,12 +972,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 +992,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 +1005,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 +1019,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++ ) { @@ -1136,7 +1343,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 +1353,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 +1421,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 +1524,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 +1541,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 */ +static void isar_SplitRenderer_PostRenderer( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ const IVAS_QUATERNION Quaternion_act ) { int16_t pos_idx, b, brange[2], ch_idx1; - int16_t num_md_bands, slot_idx, b2, 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 +1572,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 @@ -1450,7 +1657,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 +1693,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 +1702,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 +1716,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 +1770,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], @@ -1584,13 +1790,13 @@ void ivas_SplitRenderer_PostRenderer( /*-----------------------------------------------------------------------------------------* - * Function ivas_rend_CldfbSplitPostRendProcessTdIn() + * Function isar_rend_CldfbSplitPostRendProcessTdIn() * * *-----------------------------------------------------------------------------------------*/ -static void ivas_rend_CldfbSplitPostRendProcessTdIn( - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, +static void isar_rend_CldfbSplitPostRendProcessTdIn( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const IVAS_QUATERNION QuaternionPost, float output[][L_FRAME48k] ) @@ -1613,7 +1819,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,13 +1841,13 @@ static void ivas_rend_CldfbSplitPostRendProcessTdIn( /*-----------------------------------------------------------------------------------------* - * Function ivas_rend_CldfbSplitPostRendProcess() + * Function isar_rend_CldfbSplitPostRendProcess() * * *-----------------------------------------------------------------------------------------*/ -void ivas_rend_CldfbSplitPostRendProcess( - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, +void isar_rend_CldfbSplitPostRendProcess( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const IVAS_QUATERNION QuaternionPost, float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], @@ -1651,18 +1857,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,18 +1891,18 @@ 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 ) { 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; diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c similarity index 71% rename from lib_rend/ivas_splitRendererPre.c rename to lib_isar/isar_splitRendererPre.c index 25bc04dfb50dba53d411d4713ee69c5e90d3d960..3db6abf319e2badeb5bc749dbd26f1b156776177 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_isar/isar_splitRendererPre.c @@ -39,9 +39,9 @@ #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 +50,17 @@ #include "string.h" #endif +/*---------------------------------------------------------------------* + * Local function declarations + *---------------------------------------------------------------------*/ + +static void isar_SplitRenderer_GetRotMd( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + const int16_t low_res, + const int16_t ro_md_flag ); /*------------------------------------------------------------------------- * Local functions @@ -57,7 +68,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 +85,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 +105,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 +114,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 +151,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 +189,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 +237,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 +258,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 +454,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 +473,20 @@ 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; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + float quant_val; +#else float sign, quant_val; +#endif if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) { @@ -483,6 +495,24 @@ static void ivas_split_rend_quant_md( onebyquantstep = pred_1byquantstep; if ( real_only == 1 ) { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1]; + } + hMd->pred_mat_re[1][0] = 0.0f; + hMd->pred_mat_re[0][1] = 0.0f; + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - ( ( ch1 == ch2 ) ? 1.0f : 0.0f ); + quant_val = min( ISAR_SPLIT_REND_PRED_MAX_VAL, max( quant_val, ISAR_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + } + } +#else for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) @@ -493,17 +523,24 @@ static void ivas_split_rend_quant_md( hMd->pred_mat_im[ch1][ch2] = 0.0f; } } +#endif } - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + else { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) +#endif + 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 ); + } } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS } +#endif if ( real_only == 0 ) { @@ -511,36 +548,57 @@ 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; } return; } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +static void get_lr_gains( float cov_in[][BINAURAL_CHANNELS], + float cov_out[][BINAURAL_CHANNELS], + float gains[BINAURAL_CHANNELS] ) +{ + int16_t i; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gains[i] = cov_in[i][i]; + if ( gains[i] < EPSILON ) + { + gains[i] = 1.0f; + } + else + { + gains[i] = ( cov_out[i][i] ) / gains[i]; + gains[i] = sqrtf( gains[i] ); + } + } + return; +} +#endif static void ComputeCoeffs( float cov_ii_re[][BINAURAL_CHANNELS], @@ -548,12 +606,11 @@ static void ComputeCoeffs( 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]; @@ -565,7 +622,9 @@ static void ComputeCoeffs( if ( pose_type == PITCH_ONLY ) { float gd_tmp[BINAURAL_CHANNELS]; - +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); +#else for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { gd_tmp[i] = cov_ii_re[i][i]; @@ -579,6 +638,7 @@ static void ComputeCoeffs( gd_tmp[i] = sqrtf( gd_tmp[i] ); } } +#endif hMd->gd = gd_tmp[0]; hMd->gd2 = gd_tmp[1]; } @@ -587,7 +647,15 @@ static void ComputeCoeffs( if ( real_only ) { float gd_tmp[BINAURAL_CHANNELS]; - +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re[i][i] = gd_tmp[i]; + hMd->pred_mat_re2[i] = gd_tmp[i]; + set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); + } +#else for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { gd_tmp[i] = cov_ii_re[i][i]; @@ -603,11 +671,15 @@ static void ComputeCoeffs( hMd->pred_mat_re[i][i] = gd_tmp[i]; set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); } +#endif hMd->pred_mat_re[1][0] = 0.0f; hMd->pred_mat_re[0][1] = 0.0f; } else { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 ); +#endif cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); /* normalize the covariance */ @@ -625,8 +697,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 +759,32 @@ static void ComputeCoeffs( static void get_base2_bits( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int16_t num_subframes, const int16_t num_quant_strats, - const int16_t pred_real_bands_yaw[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,8 +799,14 @@ static void get_base2_bits( pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; if ( pose_type == ANY_YAW ) { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; +#else + base2bits[q] += pred_yaw_bits[q] * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS; + base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS; + base2bits[q] += pred_yaw_bits[q] * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; +#endif base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes; } else if ( pose_type == PITCH_ONLY ) @@ -739,8 +816,14 @@ static void get_base2_bits( } else { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; +#else + base2bits[q] += pred_roll_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS; + base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS; + base2bits[q] += pred_roll_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; +#endif } } } @@ -749,8 +832,8 @@ static void get_base2_bits( } -static void ivas_SplitRenderer_code_md_base2( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +static void isar_SplitRenderer_code_md_base2( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int16_t num_subframes, const int16_t pred_real_bands_yaw, @@ -760,18 +843,18 @@ 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 ) { 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,6 +880,7 @@ static void ivas_SplitRenderer_code_md_base2( { if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; @@ -805,28 +889,62 @@ 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; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } } +#else for ( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; - 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 ); + } + } +#endif for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; code = hMd->gd_idx - min_gd_idx; - 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,14 +953,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 { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; @@ -851,7 +970,7 @@ 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 ); } } } @@ -864,10 +983,42 @@ static void ivas_SplitRenderer_code_md_base2( 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 ); + } + } + } +#else + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); } } } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } +#endif } } } @@ -895,8 +1046,8 @@ static void ivas_SplitRenderer_code_md_base2( } -static void ivas_SplitRenderer_code_md_huff( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +static void isar_SplitRenderer_code_md_huff( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, const int16_t num_subframes, const int16_t pred_real_bands_yaw, @@ -906,19 +1057,19 @@ 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 ) { 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 +1081,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 +1091,76 @@ static void ivas_SplitRenderer_code_md_huff( { if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - 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 ); + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } +#else + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } - ivas_split_rend_bitstream_write_int32( pBits, code, len ); + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); } } } + + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch1], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } +#endif for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - 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 +1168,78 @@ 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 { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS for ( b = 0; b < pred_real_bands_roll; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - 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++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + } +#else + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + isar_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + + isar_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_roll_idx, max_pred_roll_idx ); for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) { for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) { - 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 ); + } + } +#endif } } } @@ -1041,24 +1266,34 @@ static void ivas_SplitRenderer_code_md_huff( } -static void ivas_SplitRenderer_quant_code( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +static void isar_SplitRenderer_quant_code( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - IVAS_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, const int16_t low_res_pre_rend_rot, +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const int16_t ro_md_flag, +#endif const int32_t target_md_bits ) { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; +#else int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; +#endif int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; - int16_t pred_real_bands_yaw[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; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t rot_axis_code, num_bits; +#endif if ( low_res_pre_rend_rot ) { @@ -1071,9 +1306,18 @@ 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 ); +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits ); + if ( num_bits > 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits ); + } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS ); +#else + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, ISAR_SPLIT_REND_ROT_AXIS_BITS ); +#endif /* code ref pose*/ for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) @@ -1084,22 +1328,27 @@ 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, +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, + pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw, + d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats ); +#else + isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw, d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, &num_quant_strats, &num_complex_bands ); - +#endif quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */ @@ -1120,20 +1369,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 +1390,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 +1398,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 +1412,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,10 +1437,10 @@ 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], + 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 ); } @@ -1283,13 +1532,13 @@ static void ivas_SplitRenderer_quant_code( /*------------------------------------------------------------------------- - * Function ivas_SplitRenderer_GetRotMd() + * Function isar_SplitRenderer_GetRotMd() * * *------------------------------------------------------------------------*/ -void ivas_SplitRenderer_GetRotMd( - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ +static void isar_SplitRenderer_GetRotMd( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ @@ -1305,9 +1554,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 +1593,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 +1616,31 @@ void ivas_SplitRenderer_GetRotMd( /*------------------------------------------------------------------------- - * Function ivas_rend_CldfbSplitPreRendProcess() + * Function isar_rend_CldfbSplitPreRendProcess() * * *------------------------------------------------------------------------*/ -void ivas_rend_CldfbSplitPreRendProcess( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, +void isar_rend_CldfbSplitPreRendProcess( + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - IVAS_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, const int32_t target_md_bits, const int16_t low_res_pre_rend_rot, const int16_t ro_md_flag ) { - push_wmops( "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 ); +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, ro_md_flag, target_md_bits ); +#else + isar_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits ); +#endif #ifdef SPLIT_POSE_CORRECTION_DEBUG float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; @@ -1461,7 +1721,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,13 +1739,13 @@ void ivas_rend_CldfbSplitPreRendProcess( /*------------------------------------------------------------------------- - * Function ivas_splitBinPreRendOpen() + * Function isar_splitBinPreRendOpen() * * *------------------------------------------------------------------------*/ -ivas_error ivas_splitBinPreRendOpen( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, +ivas_error isar_splitBinPreRendOpen( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , @@ -1493,14 +1753,14 @@ ivas_error ivas_splitBinPreRendOpen( #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" ) ); } @@ -1541,11 +1801,11 @@ 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; } @@ -1558,13 +1818,13 @@ 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 ) { if ( ( *hBinHrSplitPreRend ) != NULL ) { @@ -1585,7 +1845,7 @@ void ivas_splitBinPreRendClose( } #endif #ifdef SPLIT_POSE_CORRECTION_DEBUG - ivas_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); + isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); #endif free( ( *hBinHrSplitPreRend ) ); @@ -1597,27 +1857,28 @@ 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 ) +void isar_set_split_rend_ht_setup( + SPLIT_REND_WRAPPER *hSplitrend, + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ) { int16_t sf, i, j; - if ( 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]; } } } @@ -1627,68 +1888,13 @@ void ivas_set_split_rend_ht_setup( } -/*-------------------------------------------------------------------------* - * ivas_set_split_rend_setup() - * - * Setup IVAS split rendering - *-------------------------------------------------------------------------*/ - -ivas_error ivas_set_split_rend_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - uint8_t *splitRendBitsBuf ) -{ - int16_t sf, i, j; - - if ( ( hSplitBinRend->hSplitRendBits = (IVAS_SPLIT_REND_BITS_HANDLE) malloc( sizeof( IVAS_SPLIT_REND_BITS_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split renderer Bits buffer\n" ) ); - } - - hSplitBinRend->hSplitRendBits->bits_buf = splitRendBitsBuf; - hSplitBinRend->hSplitRendBits->bits_read = 0; - hSplitBinRend->hSplitRendBits->bits_written = 0; - hSplitBinRend->hSplitRendBits->buf_len = IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; - hSplitBinRend->hSplitRendBits->codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hSplitBinRend->hSplitRendBits->pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - hSplitBinRend->hSplitRendBits->codec_frame_size_ms = 0; - - - if ( ( hSplitBinRend->hMultiBinCldfbData = (IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); - } - - ivas_renderSplitGetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, hCombinedOrientationData->sr_pose_pred_axis ); - - if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) - { - hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; - - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; - } - } - } - } - - return IVAS_ERR_OK; -} - - /*------------------------------------------------------------------------- - * Function ivas_init_split_rend_handles() + * Function isar_init_split_rend_handles() * * *------------------------------------------------------------------------*/ -void ivas_init_split_rend_handles( +void isar_init_split_rend_handles( SPLIT_REND_WRAPPER *hSplitRendWrapper ) { int16_t i; @@ -1698,58 +1904,92 @@ 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; } - /*------------------------------------------------------------------------- * Function split_renderer_open_lc3plus() * * *------------------------------------------------------------------------*/ -static ivas_error split_renderer_open_lc3plus( +ivas_error split_renderer_open_lc3plus( SPLIT_REND_WRAPPER *hSplitRendWrapper, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, const int32_t OutSampleRate, - const int16_t num_subframes ) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE isar_frame_size +#else + const int16_t num_subframes +#endif +) { ivas_error error; int16_t i, delayBufferLength; LC3PLUS_CONFIG config; +#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + + if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Check configuration validity */ + if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" ); + } +#endif config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; - config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.isar_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; +#endif config.samplerate = OutSampleRate; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.isar_frame_duration_us = isar_frame_size_ms * 1000; +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 ); +#endif config.channels = BINAURAL_CHANNELS; - if ( ( error = 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, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 + isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, config.channels, config.lc3plus_frame_duration_us ), +#else + isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ), +#endif +#else + isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.isar_frame_duration_us / 1000 ) ), +#endif + &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) { return error; } /* This returns delay of entire LC3plus chain (enc + dec) */ - if ( ( error = 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 ); for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) @@ -1785,231 +2025,21 @@ static ivas_error split_renderer_open_lc3plus( /*------------------------------------------------------------------------- - * Function ivas_split_renderer_open() + * Function splitRendLc3plusEncodeAndWrite() * * *------------------------------------------------------------------------*/ -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; +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int32_t available_bits, #endif - uint8_t isCldfbNeeded = 0; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; +#else + const int32_t SplitRendBitRate, #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 error; @@ -2021,7 +2051,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,39 +2059,57 @@ static ivas_error splitRendLc3plusEncodeAndWrite( channel_ptrs[i] = in[i]; } - if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK ) { return error; } +#endif - 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; + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ISAR_SPLIT_REND_BITStream_write_int32( pBits, isar_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); +#endif /* Write bitstream */ - if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) +#endif { return error; } pBits->bits_written += 8 * lc3plusBitstreamSize; - pBits->codec = 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 ); +#endif return IVAS_ERR_OK; } - /*------------------------------------------------------------------------- - * Function ivas_renderMultiTDBinToSplitBinaural() + * Function isar_renderMultiTDBinToSplitBinaural() * * *------------------------------------------------------------------------*/ -static ivas_error ivas_renderMultiTDBinToSplitBinaural( +ivas_error isar_renderMultiTDBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, const IVAS_QUATERNION headPosition, const int32_t SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t isar_frame_size_ms, +#endif const int16_t codec_frame_size_ms, - IVAS_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, const int16_t max_bands, float *in[], const int16_t low_res_pre_rend_rot, @@ -2069,7 +2117,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( const int16_t ro_md_flag ) { ivas_error error; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bit_len, available_bits, target_md_bits; +#else int32_t bit_len, available_bits, target_md_bits, actual_md_bits; +#endif int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -2078,7 +2130,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 +2158,12 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( } } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS actual_md_bits = pBits->bits_written; - if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) +#endif + 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 +2197,62 @@ 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; + target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS actual_md_bits = pBits->bits_written; +#endif - 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits -= pBits->bits_written; +#else actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; +#endif pBits->codec_frame_size_ms = codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + pBits->isar_frame_size_ms = isar_frame_size_ms; +#endif - 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 { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 + 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; + } +#else + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; +#endif + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK ) +#else + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, in ) ) != IVAS_ERR_OK ) +#endif +#else if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2177,7 +2261,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 +2277,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,7 +2299,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( * *------------------------------------------------------------------------*/ -static void lc3plusTimeAlignCldfbPoseCorr( +void lc3plusTimeAlignCldfbPoseCorr( SPLIT_REND_WRAPPER *hSplitBin, float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) @@ -2240,7 +2324,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 +2352,4 @@ 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 68% rename from lib_rend/ivas_splitRenderer_utils.c rename to lib_isar/isar_splitRenderer_utils.c index da9ba62801bda41292f9cdcb08695b481fd19de4..81961fd94910400892e7e4e3500a0ddf8f3dccbe 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_isar/isar_splitRenderer_utils.c @@ -35,15 +35,9 @@ #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 +45,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,13 +80,13 @@ void ivas_mat_mult_2by2_complex( /*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_init() + * Function ISAR_SPLIT_REND_BITStream_init() * * *------------------------------------------------------------------------*/ -void ivas_split_rend_bitstream_init( - IVAS_SPLIT_REND_BITS_HANDLE pBits, +void ISAR_SPLIT_REND_BITStream_init( + ISAR_SPLIT_REND_BITS_HANDLE pBits, const int32_t buf_len_bytes, uint8_t *pbuf ) { @@ -106,13 +100,13 @@ void ivas_split_rend_bitstream_init( /*------------------------------------------------------------------------- - * Function ivas_split_rend_huffman_dec_init_min_max_len() + * Function isar_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 ) +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 +160,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 +200,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; @@ -292,7 +286,7 @@ void set_fix_rotation_mat( *------------------------------------------------------------------------*/ void set_pose_types( - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) { int16_t pos_idx; @@ -343,12 +337,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,13 +361,13 @@ 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, +int32_t ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, const int32_t bits ) { int32_t val, k, bit_val; @@ -397,13 +391,13 @@ 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, +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, const int32_t val, const int32_t bits ) { @@ -439,12 +433,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,12 +478,12 @@ 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( +int32_t isar_get_split_rend_md_target_brate( const int32_t SplitRendBitRate, const int16_t pcm_out_flag ) { @@ -530,16 +524,16 @@ 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( +int32_t isar_get_lcld_bitrate( const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) { - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { switch ( SplitRendBitRate ) { @@ -569,25 +563,50 @@ int32_t ivas_get_lcld_bitrate( return -1; } +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 +/*------------------------------------------------------------------------- + * Function isar_get_lc3plus_bitrate() + * + * + *------------------------------------------------------------------------*/ + +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int32_t nChannels, + const int32_t codecFrameDurationUs ) +{ + int32_t bitrate; + 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 ) + { + bitrate = 2 * 126000; + } + return bitrate; +} +#endif + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS /*------------------------------------------------------------------------- - * Function ivas_get_lc3plus_bitrate() + * Function isar_get_lc3plus_bitrate() * * *------------------------------------------------------------------------*/ -int32_t ivas_get_lc3plus_bitrate( +int32_t isar_get_lc3plus_bitrate( const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, const int16_t split_prerender_frame_size_ms ) { - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( poseCorrectionMode == ISAR_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; + return isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps; } - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) { return SplitRendBitRate; } @@ -599,12 +618,12 @@ int32_t ivas_get_lc3plus_bitrate( /*------------------------------------------------------------------------- - * Function ivas_get_lc3plus_bitrate_id() + * Function isar_get_lc3plus_bitrate_id() * * *------------------------------------------------------------------------*/ -int8_t ivas_get_lc3plus_bitrate_id( +int8_t isar_get_lc3plus_bitrate_id( const int32_t SplitRendBitRate ) { switch ( SplitRendBitRate ) @@ -640,14 +659,14 @@ int8_t ivas_get_lc3plus_bitrate_id( /*------------------------------------------------------------------------- - * Function ivas_mat_mult_2by2_complex() + * Function isar_get_lc3plus_size_from_id() * * *------------------------------------------------------------------------*/ -int32_t ivas_get_lc3plus_size_from_id( +int32_t isar_get_lc3plus_size_from_id( const int8_t SplitRendBitRateId, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, const int16_t split_prerender_frame_size_ms ) { int32_t bitrate; @@ -686,21 +705,22 @@ int32_t ivas_get_lc3plus_size_from_id( } } - bitrate = ivas_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms ); + bitrate = isar_get_lc3plus_bitrate( bitrate, poseCorrectionMode, split_prerender_frame_size_ms ); /* Return size in bytes */ return (int32_t) ( bitrate * split_prerender_frame_size_ms / 1000 / 8 ); } +#endif /*------------------------------------------------------------------------- - * Function 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, +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, const int16_t is_pcm_out ) { /* Valid DOF range is 0-3 */ @@ -710,26 +730,26 @@ 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" ); } @@ -755,14 +775,19 @@ ivas_error ivas_split_rend_validate_config( break; case SPLIT_REND_384k: case SPLIT_REND_512k: +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + case SPLIT_REND_768k: +#endif /* Always valid */ break; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS case SPLIT_REND_768k: - if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) + if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" ); } break; +#endif default: return IVAS_ERR_LC3PLUS_INVALID_BITRATE; } @@ -771,24 +796,45 @@ ivas_error ivas_split_rend_validate_config( { if ( pSplitRendConfig->dof == 1 ) { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + if ( pSplitRendConfig->splitRendBitRate < 34000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" ); + } +#else if ( pSplitRendConfig->splitRendBitRate < 50000 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); } +#endif } else if ( pSplitRendConfig->dof == 2 ) { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + if ( pSplitRendConfig->splitRendBitRate < 50000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 50 kbps" ); + } +#else if ( pSplitRendConfig->splitRendBitRate < 66000 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); } +#endif } else if ( pSplitRendConfig->dof == 3 ) { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + if ( pSplitRendConfig->splitRendBitRate < 82000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 82 kbps" ); + } +#else if ( pSplitRendConfig->splitRendBitRate < 128000 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); } +#endif } } @@ -797,39 +843,48 @@ 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], +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const int16_t ro_flag, +#endif + int16_t *num_quant_strats +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + , + int16_t *num_complex_bands +#endif +) { int16_t q; - *num_quant_strats = IVAS_SPLIT_REND_NUM_QUANT_STRATS; + *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS; +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; assert( *num_complex_bands <= num_md_bands ); +#endif - pred_quant_pnts_yaw[0] = 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,16 +892,40 @@ void ivas_split_rend_get_quant_params( pred_real_bands_yaw[q] = num_md_bands; pred_real_bands_roll[q] = num_md_bands; } + +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS pred_imag_bands_yaw[0] = num_md_bands; pred_imag_bands_roll[0] = num_md_bands; pred_imag_bands_yaw[1] = num_md_bands; pred_imag_bands_roll[1] = num_md_bands; - for ( q = 2; q < *num_quant_strats; q++ ) { pred_imag_bands_yaw[q] = ( q < ( *num_quant_strats - 1 ) ) ? num_md_bands : *num_complex_bands; pred_imag_bands_roll[q] = *num_complex_bands; } +#else + if ( ro_flag ) + { + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH; + } + } + else + { + for ( q = 0; q < *num_quant_strats - 2; q++ ) + { + pred_imag_bands_yaw[q] = num_md_bands; + } + pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH; + pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW; + } + + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH; + } +#endif for ( q = 0; q < *num_quant_strats; q++ ) { @@ -857,17 +936,110 @@ void ivas_split_rend_get_quant_params( return; } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisNumBits() + * + * + *------------------------------------------------------------------------*/ + +int16_t isar_renderSplitGetRot_axisNumBits( + const int16_t dof ) +{ + int16_t num_bits; + if ( dof < 3 ) + { + num_bits = 2; + } + else + { + num_bits = 0; + } + return num_bits; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisFromCode() + * + * + *------------------------------------------------------------------------*/ + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const int16_t dof, + const int16_t code ) +{ + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + + if ( dof == 1 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else if ( dof == 2 ) + { + if ( code == 0 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH; + } + } + else + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS; + } + + return rot_axis; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetCodeFromRot_axis() + * + * + *------------------------------------------------------------------------*/ + +int16_t isar_renderSplitGetCodeFromRot_axis( + const int16_t dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + int16_t *num_bits ) +{ + int16_t code = 0; + if ( dof == 1 ) + { + code = (int16_t) rot_axis; + } + else if ( dof == 2 ) + { + if ( rot_axis == DEFAULT_AXIS ) + { + code = (int16_t) rot_axis; + } + else + { + code = (int16_t) ( rot_axis - YAW_PITCH ) + 1; + } + } + else + { + code = (int16_t) DEFAULT_AXIS; + } + *num_bits = isar_renderSplitGetRot_axisNumBits( dof ); + + return code; +} +#endif /*------------------------------------------------------------------------- - * Function ivas_renderSplitGetMultiBinPoseData() + * Function isar_renderSplitGetMultiBinPoseData() * * *------------------------------------------------------------------------*/ -void ivas_renderSplitGetMultiBinPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, +void isar_renderSplitGetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_SPLIT_REND_ROT_AXIS rot_axis ) + const ISAR_SPLIT_REND_ROT_AXIS rot_axis ) { int16_t pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; const float *relative_yaw_angles; @@ -887,9 +1059,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 +1094,19 @@ void ivas_renderSplitGetMultiBinPoseData( switch ( rot_axis ) { case DEFAULT_AXIS: +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS case YAW: case PITCH: +#endif case YAW_PITCH: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; break; } +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS case ROLL: +#endif case YAW_ROLL: { num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; @@ -953,18 +1129,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 +1174,19 @@ void ivas_renderSplitGetMultiBinPoseData( /*------------------------------------------------------------------------- - * Function ivas_renderSplitUpdateNoCorrectionPoseData() + * Function isar_renderSplitUpdateNoCorrectionPoseData() * * *------------------------------------------------------------------------*/ -void ivas_renderSplitUpdateNoCorrectionPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) { pMultiBinPoseData->num_poses = 1; assert( pSplit_rend_config->dof == 0 ); pMultiBinPoseData->dof = pSplit_rend_config->dof; - assert( pSplit_rend_config->poseCorrectionMode == 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,12 +1194,12 @@ void ivas_renderSplitUpdateNoCorrectionPoseData( /*------------------------------------------------------------------------- - * Function ivas_init_multi_bin_pose_data() + * Function isar_init_multi_bin_pose_data() * * *------------------------------------------------------------------------*/ -void ivas_init_multi_bin_pose_data( +void isar_init_multi_bin_pose_data( MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) { int16_t pos_idx; @@ -1042,15 +1218,43 @@ void ivas_init_multi_bin_pose_data( return; } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error isar_framesize_to_ms( + const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ + int16_t *ms /* o : frame size in ms */ +) +{ + switch ( frame_size ) + { + case IVAS_RENDER_FRAMESIZE_5MS: + *ms = 5; + break; + case IVAS_RENDER_FRAMESIZE_10MS: + *ms = 10; + break; + case IVAS_RENDER_FRAMESIZE_20MS: + *ms = 20; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" ); + } + + return IVAS_ERR_OK; +} +#endif + /*------------------------------------------------------------------------- - * Function ivas_split_rend_choose_default_codec() + * 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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ +#endif int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ @@ -1059,35 +1263,39 @@ 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: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" ); } } - +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */ + { + *pIsar_frame_size_ms = 20; + } +#endif return IVAS_ERR_OK; } -#endif /*-------------------------------------------------------------------* * Function get_bit() @@ -1101,3 +1309,5 @@ int32_t get_bit( { return ( state & ( 1 << bit_id ) ); } + +#endif diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h new file mode 100644 index 0000000000000000000000000000000000000000..627099d90afd3b5db987630b4953028ec529f486 --- /dev/null +++ b/lib_isar/isar_stat.h @@ -0,0 +1,259 @@ +/****************************************************************************************************** + + (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" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_dec.h" +#include "isar_cnst.h" + + +/*-------------------------------------------------------------------* + * ISAR post rend constants + *-------------------------------------------------------------------*/ + +#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) +#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) + +/*-------------------------------------------------------------------* + * ISAR post rend structs + *-------------------------------------------------------------------*/ + +typedef struct +{ + int8_t headRotEnabled; + IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + +} ISAR_POST_REND_HeadRotData; + +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; +#else + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; +#endif + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; + +} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; + +typedef struct isar_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; + +} isar_split_rend_huffman_cfg_t; + +typedef struct isar_binaural_head_rot_split_rendering_huff_struct +{ + isar_split_rend_huffman_cfg_t pred[2]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_base2_code_len[2]; + isar_split_rend_huffman_cfg_t pred_roll; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_base2_code_len; + isar_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + +} ISAR_BIN_HR_SPLIT_REND_HUFF, *ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE; + +/* binaural split rendering head rotation data structure */ +typedef struct isar_binaural_head_rot_split_rendering_md_struct +{ + float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + float pred_mat_re2[BINAURAL_CHANNELS]; +#endif + float gd; + float gd2; + int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t gd_idx; + int16_t gd2_idx; + +} ISAR_BIN_HR_SPLIT_REND_MD, *ISAR_BIN_HR_SPLIT_REND_MD_HANDLE; + +typedef struct isar_binaural_head_rot_split_pre_rendering_struct +{ + ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE; + +/*----------------------------------------------------------------------------------* + * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) + *----------------------------------------------------------------------------------*/ + +typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct +{ + void *pLcld_enc; + int16_t iChannels; + LCLDEncoder *psLCLDEncoder; + float ***pppfLCLDReal; + float ***pppfLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbIn; + int16_t numFrame; +#endif + int16_t iNumIterations; + int16_t iNumBlocks; + +} ISAR_BIN_HR_SPLIT_LCLD_ENC, *ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE; + +typedef struct +{ + float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; +} ISAR_CLDFB_PLC, *ISAR_CLDFB_PLC_HANDLE; + +typedef struct +{ + ISAR_CLDFB_PLC CldfbPLC_state; + int16_t prev_bfi; + int16_t bf_count; + int16_t iNumSubSets; + +} ISAR_SPLIT_REND_PLC_STRUCT, *ISAR_SPLIT_REND_PLC_HANDLE; + +typedef struct isar_binaural_head_rot_split_rendering_lcld_dec_struct +{ + void *pLcld_dec; + int32_t iChannels; + LCLDDecoder *psLCLDDecoder; + float ***pppfDecLCLDReal; + float ***pppfDecLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbOut; + int16_t numFrame; +#endif + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + int16_t iNumBlocks; + int16_t iNumIterations; + +} ISAR_BIN_HR_SPLIT_LCLD_DEC, *ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE; + +typedef struct isar_binaural_head_rot_split_post_rendering_struct +{ + ISAR_BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + float mixer_mat_re[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[1][MAX_SPLIT_REND_MD_BANDS]; +#endif + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; +#endif + +} ISAR_BIN_HR_SPLIT_POST_REND, *ISAR_BIN_HR_SPLIT_POST_REND_HANDLE; + +typedef struct +{ + int16_t num_poses; + float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + int16_t dof; + int16_t hq_mode; + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + +} MULTI_BIN_REND_POSE_DATA; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; + int16_t first_good_frame_received; + ISAR_LC3PLUS_DEC_HANDLE hLc3plusDec; + +} ISAR_SPLIT_POST_REND_WRAPPER; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; + CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; + ISAR_LC3PLUS_ENC_HANDLE hLc3plusEnc; + float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + int32_t lc3plusDelaySamples; + +} SPLIT_REND_WRAPPER; +#endif + +#endif /* ISAR_STAT_H */ diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..12fc8e6e43991f911abf3582958b5e24fa9c78f5 --- /dev/null +++ b/lib_isar/lib_isar_post_rend.c @@ -0,0 +1,1911 @@ +/****************************************************************************************************** + + (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_stat.h" +#include "isar_prot.h" +#include "prot.h" +#include "ivas_prot.h" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_POST_REND_void_func( void ) +{ + return 0; +} + +#else + +#include "ivas_prot_rend.h" +#include +#include +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */ +typedef struct +{ + EFAP_HANDLE hEfap; + AUDIO_CONFIG speakerConfig; + const LSSETUP_CUSTOM_STRUCT *pCustomLsSetup; /* Pointer to main custom LS struct from renderer handle - doesn't need freeing */ +} EFAP_WRAPPER; + +/* Lightweight helper struct that gathers all information required for rendering + * any config to any other config. Used to simplify signatures of rendering functions. + * + * This struct should store ONLY CONST POINTERS to data existing elsewhere. + * Storing pointers instead of data itself ensures that no additional updates + * are required when any of these are changed in the renderer. Making the pointers + * const ensures that this data is only read, but not modified by the rendering functions. */ +typedef struct +{ + const int32_t *pOutSampleRate; + const AUDIO_CONFIG *pOutConfig; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; + const EFAP_WRAPPER *pEfapOutWrapper; +#endif + const ISAR_POST_REND_HeadRotData *pHeadRotData; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + const RENDER_CONFIG_HANDLE *hhRendererConfig; +#endif + const int16_t *pSplitRendBFI; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig; +#endif +} rendering_context; + +/* Common base for input structs */ +typedef struct +{ + AUDIO_CONFIG inConfig; + ISAR_POST_REND_InputId id; + IVAS_REND_AudioBuffer inputBuffer; + float gain; /* Linear, not in dB */ + rendering_context ctx; + int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ +} input_base; + +typedef struct +{ + input_base base; + ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper; + float *bufferData; + int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ + ISAR_POST_REND_BitstreamBuffer *hBits; +} input_split_post_rend; + +struct ISAR_POST_REND +{ + int32_t sampleRateOut; + + IVAS_LIMITER_HANDLE hLimiter; +#ifdef DEBUGGING + int32_t numClipping; /* Counter of clipped output samples */ +#endif + + input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; + + AUDIO_CONFIG inputConfig; + AUDIO_CONFIG outputConfig; + + ISAR_POST_REND_HeadRotData headRotData; + int16_t splitRendBFI; + + int8_t rendererConfigEnabled; + ISAR_SPLIT_REND_CONFIG_DATA splitRenderConfig; + + int16_t num_subframes; +}; + +/*-------------------------------------------------------------------* + * getAudioConfigType() + * + * + *-------------------------------------------------------------------*/ + +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const AUDIO_CONFIG config ) +{ + ISAR_POST_REND_AudioConfigType type; + + switch ( config ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL; + break; + default: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN; + break; + } + + return type; +} + + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error allocateInputBaseBufferData( + float **data, + const int16_t data_size ) +{ + *data = (float *) malloc( data_size * sizeof( float ) ); + if ( *data == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" ); + } + + return IVAS_ERR_OK; +} + +static void freeInputBaseBufferData( + float **data ) +{ + if ( *data != NULL ) + { + free( *data ); + *data = NULL; + } + + return; +} + + +static IVAS_QUATERNION quaternionInit( + void ) +{ + IVAS_QUATERNION q; + q.w = 1.0f; + q.x = q.y = q.z = 0.0f; + return q; +} + +static void convertBitsBufferToInternalBitsBuff( + const ISAR_POST_REND_BitstreamBuffer outBits, + ISAR_SPLIT_REND_BITS_HANDLE hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; + hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hBits->isar_frame_size_ms = outBits.config.isar_frame_size_ms; + hBits->lc3plus_highres = outBits.config.lc3plusHighRes; +#endif + + return; +} + +static void convertInternalBitsBuffToBitsBuffer( + ISAR_POST_REND_BitstreamBuffer *hOutBits, + const ISAR_SPLIT_REND_BITS_DATA bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; + hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hOutBits->config.isar_frame_size_ms = bits.isar_frame_size_ms; + hOutBits->config.lc3plusHighRes = bits.lc3plus_highres; +#endif + + return; +} + +static void copyBufferTo2dArray( + const IVAS_REND_AudioBuffer buffer, + float array[][L_FRAME48k] ) +{ + uint32_t smplIdx; + uint32_t chnlIdx; + const float *readPtr; + + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); + readPtr = buffer.data; + + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < (uint32_t) buffer.config.numSamplesPerChannel; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } + + return; +} + +static void accumulate2dArrayToBuffer( + float array[][L_FRAME48k], + const IVAS_REND_AudioBuffer *buffer ) +{ + int16_t smplIdx, chnlIdx; + float *writePtr; + + writePtr = buffer->data; + for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) + { + *writePtr++ += array[chnlIdx][smplIdx]; + } + } + + return; +} + +/*-------------------------------------------------------------------* + * limitRendererOutput() + * + * In-place saturation control for multichannel buffers with adaptive release time + *-------------------------------------------------------------------*/ + +#ifndef DISABLE_LIMITER +/*! r: number of clipped output samples */ +static int32_t limitRendererOutput( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + float *output, /* i/o: I/O buffer */ + const int16_t output_frame, /* i : number of samples per channel in the buffer */ + const float threshold /* i : signal amplitude above which limiting starts to be applied */ +) +{ + int16_t i; + float **channels; + int16_t num_channels; + int32_t numClipping = 0; + + /* return early if given bad parameters */ + if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) + { + return 0; + } + + channels = hLimiter->channel_ptrs; + num_channels = hLimiter->num_channels; + + for ( i = 0; i < num_channels; ++i ) + { + channels[i] = output + i * output_frame; + } + + limiter_process( hLimiter, output_frame, threshold, 0, NULL ); + + /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ + for ( i = 0; i < output_frame * num_channels; ++i ) + { +#ifdef DEBUGGING + if ( output[i] < INT16_MIN || output[i] > INT16_MAX ) + { + ++numClipping; + } +#endif + + output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX ); + } + + return numClipping; +} +#endif + + +/*-------------------------------------------------------------------* + * validateOutputSampleRate() + * + * + *-------------------------------------------------------------------*/ + +static ivas_error validateOutputSampleRate( + const int32_t sampleRate, + const AUDIO_CONFIG outConfig ) +{ + if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } + else + { + /* Otherwise rendering to binaural, support the same set as IVAS decoder */ + switch ( sampleRate ) + { + case 8000: + case 16000: + case 32000: + case 48000: + return IVAS_ERR_OK; + } + + return IVAS_ERR_INVALID_SAMPLING_RATE; + } +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error initLimiter( + IVAS_LIMITER_HANDLE *phLimiter, + const int16_t numChannels, + const int32_t sampleRate ) +{ + ivas_error error; + + /* If re-initializing with unchanged values, return early */ + if ( *phLimiter != NULL && ( *phLimiter )->num_channels == numChannels && ( *phLimiter )->sampling_rate == sampleRate ) + { + return IVAS_ERR_OK; + } + + /* Support re-init: close if already allocated */ + if ( *phLimiter != NULL ) + { + ivas_limiter_close( phLimiter ); + } + + if ( ( error = ivas_limiter_open( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static ivas_error initHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + int16_t i, crossfade_len; + float tmp; + + /* Head rotation is enabled by default */ + hIvasRend->headRotData.headRotEnabled = 1; + + /* Initialize 5ms crossfade */ + crossfade_len = L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES; + tmp = 1.f / ( crossfade_len - 1 ); + for ( i = 0; i < crossfade_len; i++ ) + { + hIvasRend->headRotData.crossfade[i] = i * tmp; + } + + /* Initialize with unit quaternions */ + for ( i = 0; i < hIvasRend->num_subframes; ++i ) + { + hIvasRend->headRotData.headPositions[i] = quaternionInit(); + } + + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; + + return IVAS_ERR_OK; +} + + +static void initRendInputBase( + input_base *inputBase, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + const rendering_context rendCtx, + float *dataBuf, + const int16_t dataBufSize ) +{ + inputBase->inConfig = inConfig; + inputBase->id = id; + inputBase->gain = 1.0f; + inputBase->ctx = rendCtx; + inputBase->numNewSamplesPerChannel = 0; + + inputBase->inputBuffer.config.numSamplesPerChannel = 0; + inputBase->inputBuffer.config.numChannels = 0; + inputBase->inputBuffer.data = dataBuf; + if ( inputBase->inputBuffer.data != NULL ) + { + set_zero( inputBase->inputBuffer.data, dataBufSize ); + } + + return; +} + + +static rendering_context getRendCtx( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + rendering_context ctx; + + /* Note: when refactoring this, always take the ADDRESS of a member of the + * renderer struct, so that the context stores a POINTER to the member, even + * if the member is a pointer or handle itself. */ + ctx.pOutConfig = &hIvasRend->outputConfig; + ctx.pOutSampleRate = &hIvasRend->sampleRateOut; + ctx.pHeadRotData = &hIvasRend->headRotData; + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ctx.pSplitRenderConfig = &hIvasRend->splitRenderConfig; +#endif + + return ctx; +} + + +static ivas_error getRendInputNumChannels( + const void *rendInput, + int16_t *numInChannels ) +{ + /* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba). + Assumptions: - input_base is always the first member in the input struct */ + (void) rendInput; + + *numInChannels = 2; + + return IVAS_ERR_OK; +} + + +static ivas_error updateSplitPostRendPanGains( + input_split_post_rend *inputSplitPostRend, + const AUDIO_CONFIG outConfig, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t num_subframes +#endif +) +{ + ivas_error error; + rendering_context rendCtx; + LC3PLUS_CONFIG config; + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + + (void) outConfig; + + rendCtx = inputSplitPostRend->base.ctx; + isar_renderSplitGetMultiBinPoseData( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 ); +#endif + config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.isar_frame_duration_us = hRendCfg->isar_frame_size_ms * 1000; +#else + if ( num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES ) + { + if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; + } + else + { + config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + } + iNumLCLDIterationsPerFrame = 1; + } + else + { + config.isar_frame_duration_us = 20000; + } +#endif + + if ( hRendCfg->codec_frame_size_ms > 0 ) + { + iNumLCLDIterationsPerFrame = (int16_t) config.isar_frame_duration_us / ( 1000 * hRendCfg->codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); + iNumBlocksPerFrame = CLDFB_NO_COL_MAX * hRendCfg->codec_frame_size_ms / 20; + } + else + { + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + } + + config.channels = BINAURAL_CHANNELS; + config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate; + + if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + if ( ( error = isar_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *inputSplitPostRend->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + if ( ( error = ISAR_LC3PLUS_DEC_Open( config, + &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( ( error = isar_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static ivas_error setRendInputActiveSplitPostRend( + void *input, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t num_subframes +#endif +) +{ + ivas_error error; + rendering_context rendCtx; + AUDIO_CONFIG outConfig; + input_split_post_rend *inputSplitPostRend; + + inputSplitPostRend = (input_split_post_rend *) input; + rendCtx = inputSplitPostRend->base.ctx; + outConfig = *rendCtx.pOutConfig; + + if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } + + initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); + inputSplitPostRend->numCachedSamples = 0; + + if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static void clearInputSplitRend( + input_split_post_rend *inputSplitRend ) +{ + rendering_context rendCtx; + + rendCtx = inputSplitRend->base.ctx; + + freeInputBaseBufferData( &inputSplitRend->bufferData ); + + initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + + if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + { + isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); + } + + if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); + } + + if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * ISAR_POST_REND_open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_open( + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t num_subframes /* i : number of subframes */ +) +{ + int16_t i; + ISAR_POST_REND_HANDLE hIvasRend; + ivas_error error; + int16_t numOutChannels; + + (void) asHrtfBinary; + (void) nonDiegeticPan; + (void) nonDiegeticPanGain; + + /* Validate function arguments */ + if ( phIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + *phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) ); + if ( *phIvasRend == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + hIvasRend = *phIvasRend; + hIvasRend->sampleRateOut = outputSampleRate; + hIvasRend->outputConfig = outConfig; + hIvasRend->hLimiter = NULL; + hIvasRend->num_subframes = 1; +#ifdef DEBUGGING + hIvasRend->numClipping = 0; +#endif + hIvasRend->num_subframes = num_subframes; + + /* Initialize limiter */ + if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize headrotation data */ + if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize inputs */ + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + isar_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); + + hIvasRend->splitRendBFI = 0; + hIvasRend->inputsSplitPost[i].bufferData = NULL; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_NumOutChannels() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_NumOutChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *numOutChannels /* o : number of output channels */ +) +{ + /* Validate function arguments */ + if ( hIvasRend == NULL || numOutChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *numOutChannels = 2; + + return IVAS_ERR_OK; +} + + +static IVAS_REND_InputId makeInputId( + AUDIO_CONFIG config, + const int32_t inputIndex ) +{ + /* Put config type in second byte (from LSB), put index + 1 in first byte + * + * Index is incremented here so that a valid ID can never be 0. */ + return (IVAS_REND_InputId) ( ( ( (uint32_t) isar_getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); +} + + +static ivas_error getInputById( + ISAR_POST_REND_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + void **ppInput ) +{ + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetInputGain() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetInputGain( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const float gain /* i : linear gain (not in dB) */ +) +{ + input_base *inputBase; + ivas_error error; + + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Hoo\n" ); + return error; + } + + inputBase->gain = gain; + + return IVAS_ERR_OK; +} + +static ivas_error getConstInputById( + ISAR_POST_REND_CONST_HANDLE hIvasRend, + const ISAR_POST_REND_InputId inputId, + const void **ppInput ) +{ + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + const input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + + +static ivas_error findFreeInputSlot( + const void *inputs, + const int32_t inputStructSize, + const int32_t maxInputs, + int32_t *inputIndex ) +{ + /* Using a void pointer and a separately provided size is a hack for this function + to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). + Assumptions: + - input_base is always the first member in the input struct + - provided size is correct + */ + + int32_t i; + bool canAddInput; + const uint8_t *pByte; + const input_base *pInputBase; + + canAddInput = false; + + /* Find first unused input in array */ + for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize ) + { + pInputBase = (const input_base *) pByte; + + if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + *inputIndex = i; + canAddInput = true; + break; + } + } + + if ( !canAddInput ) + { + return IVAS_ERR_TOO_MANY_INPUTS; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_AddInput() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +) +{ + ivas_error error; + int32_t maxNumInputsOfType; + void *inputsArray; + int32_t inputStructSize; + ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA * +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t +#endif + ); + int32_t inputIndex; + + /* Validate function arguments */ + if ( hIvasRend == NULL || inputId == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + switch ( isar_getAudioConfigType( inConfig ) ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; + inputsArray = hIvasRend->inputsSplitPost; + inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); + activateInput = setRendInputActiveSplitPostRend; + break; + default: + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + + /* Find first free input in array corresponding to input type */ + if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) + { + return error; + } + + *inputId = makeInputId( inConfig, inputIndex ); + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + hIvasRend->num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetInputNumChannels() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetInputNumChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + int16_t *numChannels /* o : number of channels of the input */ +) +{ + ivas_error error; + const input_base *pInput; + + /* Validate function arguments */ + if ( hIvasRend == NULL || numChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetDelay( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer state */ + int16_t *nSamples, /* o : Renderer delay in samples */ + int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ +) +{ + int16_t i; + int32_t latency_ns; + int32_t max_latency_ns; + + /* Validate function arguments */ + if ( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *timeScale = hIvasRend->sampleRateOut; + *nSamples = 0; + max_latency_ns = 0; + + /* Compute the maximum delay across all inputs */ + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + if ( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + { + latency_ns = 0; + if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) + { + int32_t lc3plusDelaySamples; + ISAR_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); + latency_ns = (int32_t) roundf( lc3plusDelaySamples * 1000000000.f / *timeScale ); + } + if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + max_latency_ns = max( max_latency_ns, latency_ns ); + } + } + + *nSamples = (int16_t) roundf( (float) max_latency_ns * *timeScale / 1000000000.f ); + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_FeedInputAudio() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_FeedInputAudio( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +) +{ + ivas_error error; + input_base *inputBase; + int16_t numInputChannels; + int16_t cldfb2tdSampleFact; + + /* Validate function arguments */ + if ( hIvasRend == NULL || inputAudio.data == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1; + + if ( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); + } + + if ( inputAudio.config.numChannels <= 0 || MAX_INPUT_CHANNELS < inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Foo\n" ); + return error; + } + + if ( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( numInputChannels != inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + inputBase->inputBuffer.config = inputAudio.config; + + mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + + inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_InitConfig() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_InitConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ +) +{ + bool rendererConfigEnabled; + + rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ); + + if ( rendererConfigEnabled ) + { + hIvasRend->rendererConfigEnabled = 1; + } + else + { + hIvasRend->rendererConfigEnabled = 0; + } + + if ( rendererConfigEnabled ) + { + hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k; + hIvasRend->splitRenderConfig.dof = 3; + hIvasRend->splitRenderConfig.hq_mode = 0; + hIvasRend->splitRenderConfig.codec_delay_ms = 0; + hIvasRend->splitRenderConfig.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#endif + hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetRenderConfig() + * + * + *-------------------------------------------------------------------*/ + +int16_t ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +) +{ + ISAR_SPLIT_REND_CONFIG_DATA hRCin; + + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRCin = hIvasRend->splitRenderConfig; + + splitRenderConfig->splitRendBitRate = SPLIT_REND_768k; + splitRenderConfig->dof = 3; + splitRenderConfig->hq_mode = 0; + splitRenderConfig->codec_delay_ms = 0; + splitRenderConfig->codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRenderConfig->isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#endif + splitRenderConfig->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRenderConfig->poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + splitRenderConfig->rendererSelection = hRCin.rendererSelection; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_FeedSplitBinauralBitstream() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +) +{ + ivas_error error; + input_base *inputBase; + input_split_post_rend *inputSplitPostRend; + + /* Validate function arguments */ + if ( hIvasRend == NULL || hBits == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Goo\n" ); + return error; + } + + inputSplitPostRend = (input_split_post_rend *) inputBase; + inputSplitPostRend->hBits = hBits; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetHeadRotation() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const int16_t sf_idx /* i : subframe index */ +) +{ + IVAS_QUATERNION rotQuat; + + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( isar_getAudioConfigType( hIvasRend->outputConfig ) != ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ) + { + /* Head rotation can be set only with binaural output */ + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + hIvasRend->headRotData.headRotEnabled = 1; + + /* check for Euler angle signaling */ + if ( headRot.w == -3.0f ) + { + Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); + } + else + { + rotQuat = headRot; + } + + hIvasRend->headRotData.headPositions[sf_idx] = rotQuat; + hIvasRend->headRotData.Pos[sf_idx] = Pos; + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetSplitRendBFI() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i: BFI flag */ +) +{ + hIvasRend->splitRendBFI = bfi; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + + +static ivas_error splitBinLc3plusDecode( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE bits, + float outputBuffer[BINAURAL_CHANNELS][L_FRAME48k], +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction, +#endif + const int16_t SplitRendBFI ) +{ + ivas_error error; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t lc3plusBitstreamSize; +#else + int32_t lc3plusBitrateId, lc3plusBitstreamSize; +#endif + + push_wmops( "splitBinLc3plusDecode" ); + assert( hSplitBin->hLc3plusDec != NULL ); + + for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = outputBuffer[i]; + } + + if ( SplitRendBFI == 0 ) + { + /* Find next byte boundary */ + while ( bits->bits_read % 8 != 0 ) + { + ++bits->bits_read; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Size is in bytes */ + assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 ); + lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8; +#else + /* Read LC3plus bitstream size info */ + lc3plusBitrateId = ISAR_SPLIT_REND_BITStream_read_int32( bits, 8 ); + lc3plusBitstreamSize = isar_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.isar_frame_duration_us / 1000 ) ); +#endif + + if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ISAR_LC3PLUS_DEC_Conceal( hSplitBin->hLc3plusDec, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + pop_wmops(); + return IVAS_ERR_OK; +} + + +static ivas_error renderSplitBinauralWithPostRot( + input_split_post_rend *splitBinInput, + IVAS_REND_AudioBuffer outAudio, + const int16_t SplitRendBFI, + const int16_t num_subframes ) +{ + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + ivas_error error; + float Cldfb_RealBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t sf_idx, ch_idx; + ISAR_SPLIT_REND_BITS_DATA bits; + float tmpCrendBuffer[BINAURAL_CHANNELS][L_FRAME48k]; + float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin; + int8_t isPostRendInputCldfb; + int16_t chnlIdx, slotIdx, smplIdx; + int16_t preRendFrameSize_ms; + int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; + int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; + float *readPtr, *writePtr; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + uint32_t ivas_frame_duration_us; +#endif + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + const ISAR_POST_REND_HeadRotData *pHeadRotData; + + isPostRendInputCldfb = 0; + push_wmops( "renderSplitBinauralWithPostRot" ); + error = IVAS_ERR_OK; + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( outAudio.config.numSamplesPerChannel / *splitBinInput->base.ctx.pOutSampleRate > splitBinInput->hBits->config.isar_frame_size_ms ) + { + return IVAS_ERR_INTERNAL_FATAL; + } +#endif + + pHeadRotData = splitBinInput->base.ctx.pHeadRotData; + hSplitBin = &splitBinInput->splitPostRendWrapper; + convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_duration_us = 20000; + if ( splitBinInput->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ivas_frame_duration_us = splitBinInput->splitPostRendWrapper.hLc3plusDec->config.isar_frame_duration_us; + } +#endif + + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + if ( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + iNumBlocksPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumBlocks; + iNumLCLDIterationsPerFrame = splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec->iNumIterations; + } + + outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / num_subframes; + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx]; + } + + if ( !SplitRendBFI ) + { + hSplitBin->first_good_frame_received = 1; + } + + if ( hSplitBin->first_good_frame_received == 1 ) + { + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( !SplitRendBFI ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); +#else + isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); +#endif + } + } + + /*copy pose correction after MD is parsed*/ + hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; + + /* decode audio */ + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isPostRendInputCldfb = 1; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel; +#else + preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000; + + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); +#endif + + outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; + numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + if ( splitBinInput->numCachedSamples == 0 ) + { + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); + + /* copy data over to 5ms buffer */ + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + { + mvr2r( Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx], Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx], CLDFB_NO_CHANNELS_MAX ); + } + } + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numColPerChannelCacheSize; + writePtr = splitBinInput->bufferData; + for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + } + } + } + else + { + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + bits.pose_correction, +#endif + SplitRendBFI ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* cache the remaining decoded audio */ + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); + mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); + } + } + else + { + /* copy from cache */ + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); + readPtr = splitBinInput->bufferData; + isPostRendInputCldfb = 1; + + readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + splitBinInput->numCachedSamples -= outBufNumColPerChannel; + } + else + { + int16_t readOffset = numSamplesPerChannelCacheSize - splitBinInput->numCachedSamples; + mvr2r( splitBinInput->bufferData + readOffset, &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvr2r( splitBinInput->bufferData + readOffset + numSamplesPerChannelCacheSize, &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; + } + } + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + if ( splitBinInput->numCachedSamples == 0 ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + preRendFrameSize_ms = splitBinInput->base.ctx.pSplitRenderConfig->isar_frame_size_ms; +#else + preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000; +#endif + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); + numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + } + else + { + splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; + } + } + + /* apply pose correction if enabled */ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) + { + /* 0DOF with LCLD codec requires CLDFB synthesis */ + int16_t slot_idx; + + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + float *RealBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural_5ms[sf_idx][ch_idx][slot_idx]; + } + + cldfbSynthesis( RealBuffer, + ImagBuffer, + &( tmpCrendBuffer[ch_idx][sf_idx * outBufNumSamplesPerChannel] ), + hSplitBin->hBinHrSplitPostRend->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + hSplitBin->hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + } + else if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + mvr2r( &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[0], outBufNumSamplesPerChannel ); + mvr2r( &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], tmpCrendBuffer_sf[1], outBufNumSamplesPerChannel ); + + isar_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb ); + + mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + } + } + } + else + { + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + } + + convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + pop_wmops(); + return error; +} + +static ivas_error renderInputSplitBin( + input_split_post_rend *splitBinInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio, + const int16_t SplitRendBFI, + const int16_t num_subframes ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = splitBinInput->base.inputBuffer; + + splitBinInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc( inAudio.data, + splitBinInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + switch ( outConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + return error; +} + +static ivas_error renderActiveInputsSplitBin( + ISAR_POST_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + input_split_post_rend *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_getSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_getSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +) +{ + ivas_error error; + int16_t numOutChannels; + int16_t cldfb2tdSampleFact; + + /* Validate function arguments */ + if ( hIvasRend == NULL || outAudio.data == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1; + + if ( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) + { + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + + if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + if ( isar_getAudioConfigType( hIvasRend->outputConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL && + ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + + /* Clear original output buffer */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + + if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetSplitBinauralSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool *needNewFrame ) +{ + ivas_error error; + + if ( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ +) +{ + uint16_t i; + ISAR_POST_REND_HANDLE hIvasRend; + + /* Validate function arguments */ + if ( phIvasRend == NULL || *phIvasRend == NULL ) + { + return; + } + hIvasRend = *phIvasRend; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); + } + + ivas_limiter_close( &hIvasRend->hLimiter ); + + free( hIvasRend ); + *phIvasRend = NULL; + + return; +} + + +ivas_error ISAR_REND_SetSplitRendBitstreamHeader( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, /* i: isar codec frame size setting */ + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif +) +{ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + hIvasRend->splitRenderConfig.codec = codec; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms; +#endif + hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms; + hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres; +#endif + return IVAS_ERR_OK; +} + +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetNoCLipping() + * + * + *-------------------------------------------------------------------*/ + +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + return hIvasRend->numClipping; +} + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_CONST_HANDLE hIvasRend ) +{ + if ( hIvasRend->hLimiter == NULL ) + { + return 0; + } + + return hIvasRend->hLimiter->cnt_frames_limited; +} +#endif + + +#endif diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..7c06895e689c2412ce69baa182445268025bab0a --- /dev/null +++ b/lib_isar/lib_isar_post_rend.h @@ -0,0 +1,231 @@ +/****************************************************************************************************** + + (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" + + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_POST_REND_void_func( void ); + +#else + +/*---------------------------------------------------------------------* + * Renderer constants + *---------------------------------------------------------------------*/ + +#define RENDERER_MAX_ISAR_MD_INPUTS 1 +#define RENDERER_MAX_BIN_INPUTS 1 + +/*---------------------------------------------------------------------* + * Renderer structures + *---------------------------------------------------------------------*/ + +typedef struct +{ + int32_t bufLenInBytes; + int32_t bitsWritten; + int32_t bitsRead; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + int16_t codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plusHighRes; +#endif +} ISAR_POST_REND_BitstreamBufferConfig; + +typedef struct +{ + ISAR_POST_REND_BitstreamBufferConfig config; + uint8_t *bits; +} ISAR_POST_REND_BitstreamBuffer; + +typedef enum +{ + ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL = 0, + ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN, +} ISAR_POST_REND_AudioConfigType; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + const float *data; +} ISAR_POST_REND_ReadOnlyAudioBuffer; + +typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE; +typedef struct ISAR_POST_REND const *ISAR_POST_REND_CONST_HANDLE; + +typedef uint16_t ISAR_POST_REND_InputId; + +typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL +{ + ISAR_POST_REND_COMPLEXITY_LEVEL_ONE = 1, + ISAR_POST_REND_COMPLEXITY_LEVEL_TWO = 2, + ISAR_POST_REND_COMPLEXITY_LEVEL_THREE = 3 +} ISAR_POST_REND_COMPLEXITY_LEVEL; + + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * Renderer function prototypes + *----------------------------------------------------------------------------------*/ + +/* Functions to be called before rendering */ + +ivas_error ISAR_POST_REND_open( + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t num_subframes /* i : number of subframes */ +); + +/* Functions to be called before/during rendering */ + +ivas_error ISAR_POST_REND_NumOutChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *numOutChannels /* o : number of output channels */ +); + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +); + +ivas_error ISAR_POST_REND_SetInputGain( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const float gain /* i : linear gain (not in dB) */ +); + +ivas_error ISAR_POST_REND_GetInputNumChannels( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + int16_t *numChannels /* o : number of channels of the input */ +); + +ivas_error ISAR_POST_REND_GetDelay( + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *nSamples, /* o : Renderer delay in samples */ + int32_t *timeScale /* o : Time scale of the delay, equal to renderer output sampling rate */ +); + +/* Functions to be called during rendering */ + +ivas_error ISAR_POST_REND_FeedInputAudio( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +); + +ivas_error ISAR_POST_REND_InitConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG outAudioConfig /* i : output audioConfig */ +); + +int16_t ISAR_POST_REND_GetRenderConfig( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const ISAR_SPLIT_REND_CONFIG_HANDLE splitRenderConfig /* o : Render configuration handle */ +); + +ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const ISAR_POST_REND_InputId inputId, /* i : ID of the input */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +); + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool* needNewFrame +); + +ivas_error ISAR_POST_REND_SetHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ + const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ + const int16_t sf_idx /* i : subframe index */ +); + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i: BFI flag */ +); + + +ivas_error ISAR_POST_REND_getSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +); + +/* Functions to be called after rendering */ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */ +); + +ivas_error ISAR_REND_SetSplitRendBitstreamHeader( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, /* i: isar frame size setting */ + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif +); + +#ifdef DEBUGGING +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ +); + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ +); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ + +/* clang-format on */ + +#endif /* LIB_ISAR_POST_REND_H */ diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c new file mode 100644 index 0000000000000000000000000000000000000000..15e08660e5a0e517388f4d7e1dd323a6109e7955 --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.c @@ -0,0 +1,508 @@ +/****************************************************************************************************** + + (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" + + +#ifndef SPLIT_REND_WITH_HEAD_ROT +int32_t ISAR_PRE_REND_void_func( void ) +{ + return 0; +} + +#else + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_PRE_REND_open( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ + const int32_t output_Fs, /* i: output sampling rate */ + const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ +#else + const int16_t num_subframes, /* i: number of subframes */ +#endif + const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */ +) +{ + ivas_error error, ch, num_ch; + uint8_t isCldfbNeeded = 0; + + int16_t cldfb_in_flag_local = cldfb_in_flag; + + if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + &pSplitRendConfig->isar_frame_size_ms, +#endif + &pSplitRendConfig->codec_frame_size_ms, + cldfb_in_flag_local, + pcm_out_flag, (int16_t) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_size +#else + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( mixed_td_cldfb_flag ) + { + cldfb_in_flag_local = 0; + } + + if ( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( cldfb_in_flag_local == 0 ) + { + isCldfbNeeded = 1; + } + else if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + else if ( pcm_out_flag && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + + hSplitBinRend->hCldfbHandles = NULL; + + if ( isCldfbNeeded ) + { + if ( ( hSplitBinRend->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + + num_ch = hSplitBinRend->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ), + CLDFB_ANALYSIS, + output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + if ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + OutSampleRate +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( pcm_out_flag == 0 ) + { + if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_size +#else + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + int16_t iNumBlocksPerFrame; + iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; + + if ( ( error = isar_splitBinLCLDEncOpen( &hSplitBinRend->hSplitBinLCLDEnc, output_Fs, BINAURAL_CHANNELS, isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitBinRend->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_close() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_PRE_REND_close( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ +) +{ + int16_t i; + + if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) + { + isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); + } + + if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + { + isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); + } + + if ( hSplitBinRend->hCldfbHandles != NULL ) + { + int16_t num_ch, ch; + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ); + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + } + + free( hSplitBinRend->hCldfbHandles ); + hSplitBinRend->hCldfbHandles = NULL; + } + + if ( hSplitBinRend->hLc3plusEnc != NULL ) + { + ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers[i] ); + hSplitBinRend->lc3plusDelayBuffers[i] = NULL; + } + } + + if ( pSplitRendEncBuffer != NULL ) + { + + if ( pSplitRendEncBuffer->data != NULL ) + { + free( pSplitRendEncBuffer->data ); + pSplitRendEncBuffer->data = NULL; + } + + pSplitRendEncBuffer->config.numChannels = 0; + pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + } + + return; +} + +/*-------------------------------------------------------------------------* + * ISAR_PRE_REND_GetMultiBinPoseData() + * + * + *-------------------------------------------------------------------------*/ + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ +) +{ + isar_renderSplitGetMultiBinPoseData( pSplit_rend_config, pMultiBinPoseData, rot_axis ); +} + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_MultiBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i: Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t isar_frame_size_ms, /* i: ISAR framesize */ +#endif + int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + const int16_t max_bands, /* i: CLDFB bands */ + float *output[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ + const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ + const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */ +) +{ + ivas_error error; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bit_len, target_md_bits, available_bits; +#else + int32_t bit_len, target_md_bits, actual_md_bits, available_bits; +#endif + + error = IVAS_ERR_OK; + push_wmops( "isar_pre_rend_MultiBinToSplitBinaural" ); + + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData ); + set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); + } + + if ( cldfb_in_flag == 0 ) + { + /*TD input*/ + /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ + error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, + headPosition, + SplitRendBitRate, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + isar_frame_size_ms, +#endif + codec_frame_size_ms, + pBits, + max_bands, + output, + low_res_pre_rend_rot, + pcm_out_flag, + ro_md_flag ); + + pop_wmops(); + return error; + } + + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + /* Time-align pose correction to delay of LC3plus */ + lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + + isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); + } + + if ( pcm_out_flag == 0 ) + { + pBits->codec = splitCodec; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits -= pBits->bits_written; +#else + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; +#endif + pBits->codec_frame_size_ms = codec_frame_size_ms; + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + } + else + { + int16_t ch, slot_idx, num_slots, ivas_fs; + ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; + num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20; + /* CLDFB synthesis of main pose */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; + float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; + Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; + } + + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef LC3PLUS_LEA_COMPAT_BITRATES_48_6 + 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; + } +#else + available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; +#endif + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, output ) ) != IVAS_ERR_OK ) +#else + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + else + { + int16_t ch, slot_idx; + /* CLDFB synthesis of main pose */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; + float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; + Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; + } + + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + } + + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + if ( pcm_out_flag ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + } + else + { + bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; + bit_len = SplitRendBitRate * bit_len / 1000; + } + } + + while ( pBits->bits_written < bit_len ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + return error; +} + +#endif diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h new file mode 100644 index 0000000000000000000000000000000000000000..a1e658ac123ba0dd78dbec8b1e75be99206e2a7e --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.h @@ -0,0 +1,91 @@ +/****************************************************************************************************** + + (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" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_PRE_REND_void_func( void ); + +#else + +ivas_error ISAR_PRE_REND_open( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ + const int32_t output_Fs, /* i: output sampling rate */ + const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ +#else + const int16_t num_subframes, /* i: number of subframes */ +#endif + const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */ +); + +void ISAR_PRE_REND_close( + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ +); + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ +); + +ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i: Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t isar_frame_size_ms, /* i: ISAR framesize */ +#endif + int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + const int16_t max_bands, /* i: CLDFB bands */ + float *output[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ + const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ + const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */ +); + +#endif +#endif /* LIB_ISAR_PRE_REND_H */ diff --git a/lib_lc3plus/.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..d7d24d1d5890d98e6f80190fe64c7150fd452488 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1642,7 +1642,11 @@ 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; @@ -1694,6 +1698,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 +1724,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 +1739,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 +1757,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++; } } @@ -2036,8 +2067,8 @@ ivas_error ivas_rend_crendProcessSplitBin( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig, const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], @@ -2071,7 +2102,7 @@ ivas_error ivas_rend_crendProcessSplitBin( /* save current head positions */ pCombinedOrientationDataLocal = hCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) { @@ -2166,9 +2197,8 @@ ivas_error ivas_rend_crendProcessSplitBin( return IVAS_ERR_OK; } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crend_ProcessSubframesSplitBin() * @@ -2225,7 +2255,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 ) { diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 33a33cdcf3178ce4f88137870fd3fd3621d91e1a..82ee76a49a84cf8aaaa26c9a9858db6a1a02c0ce 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -99,8 +99,9 @@ static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const int16_t num_freq_bands, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); #ifdef SPLIT_REND_WITH_HEAD_ROT -static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); -static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); #else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); #endif @@ -153,9 +154,15 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; #ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t pos_idx; + int16_t num_poses, pos_idx; + + num_poses = 1; + if ( st_ivas->hSplitBinRend != NULL ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + } - for ( pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; #else @@ -801,7 +808,7 @@ static void ivas_dirac_dec_binaural_internal( subFrameTotalEne, IIReneLimiter ); ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); #endif nchanSeparateChannels = 0; @@ -818,7 +825,11 @@ static void ivas_dirac_dec_binaural_internal( hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); #ifdef SPLIT_REND_WITH_HEAD_ROT - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + pMultiBinPoseData = NULL; + if ( st_ivas->hSplitBinRend != NULL ) + { + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; + } #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) @@ -832,10 +843,10 @@ static void ivas_dirac_dec_binaural_internal( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } } @@ -905,10 +916,10 @@ static void ivas_dirac_dec_binaural_internal( /* copy from temporary buffer to the main split rendering buffer */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } @@ -984,8 +995,8 @@ static void ivas_dirac_dec_decorrelate_slot( #ifdef SPLIT_REND_WITH_HEAD_ROT static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, @@ -1148,8 +1159,8 @@ static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, @@ -3373,10 +3384,11 @@ static void ivas_masa_ext_rend_parambin_internal( const int16_t subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] #else - const int16_t subframe ) + const int16_t subframe #endif +) { DIRAC_DEC_BIN_HANDLE hDiracDecBin; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -3616,13 +3628,14 @@ void ivas_masa_ext_rend_parambin_render( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ #ifdef SPLIT_REND_WITH_HEAD_ROT - const int16_t num_subframes, /* i : number of subframes to render */ - const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) /* o : rendered orientations for split rend. imag part of cldfb */ + const int16_t num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ #else - const int16_t num_subframes ) /* i : number of subframes to render */ + const int16_t num_subframes /* i : number of subframes to render */ #endif +) { int16_t subframe; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; diff --git a/lib_rend/ivas_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..4aac09eafadb74e801436de0227ad18a247e76ec 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 @@ -63,12 +60,15 @@ static void angles_to_vec( const float radius, const float azimuth, const float *---------------------------------------------------------------------*/ ivas_error ivas_td_binaural_open_unwrap( - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ - const int32_t output_Fs, /* i : Output sampling rate */ - const int16_t nchan_transport, /* i : Number of channels */ - 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) */ + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ + const int32_t output_Fs, /* i : Output sampling rate */ + const int16_t nchan_transport, /* i : Number of channels */ + 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) */ +#ifdef CONF_DISTATT + const float *distAtt, /* i : Distance attenuation (used for ISM) */ +#endif 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 +82,9 @@ ivas_error ivas_td_binaural_open_unwrap( float Pos[3]; float Dir[3]; TDREND_DirAtten_t *DirAtten_p; +#ifdef CONF_DISTATT + TDREND_DistAtten_t DistAtten; +#endif int16_t nchan_rend; ivas_error error; @@ -187,6 +190,13 @@ ivas_error ivas_td_binaural_open_unwrap( DirAtten_p->ConeOuterAngle = 360.0f; DirAtten_p->ConeOuterGain = 1.0f; +#ifdef CONF_DISTATT + DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; + DistAtten.MaxDist = 15.75f; + DistAtten.RefDist = 1.0f; + DistAtten.RollOffFactor = 1.0f; +#endif + if ( ( error = TDREND_MIX_SRC_SetPos( pBinRendTd, nS, Pos ) ) != IVAS_ERR_OK ) { return error; @@ -206,6 +216,12 @@ ivas_error ivas_td_binaural_open_unwrap( { return error; } +#ifdef CONF_DISTATT + if ( ( error = TDREND_MIX_SRC_SetDistAtten( pBinRendTd, nS, &DistAtten ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif } } @@ -227,11 +243,32 @@ ivas_error ivas_td_binaural_open_unwrap( DirAtten_p->ConeOuterAngle = directivity[nS * 3 + 1]; DirAtten_p->ConeOuterGain = directivity[nS * 3 + 2]; } - +#ifdef CONF_DISTATT + 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]; + } +#endif if ( ( error = TDREND_MIX_SRC_SetDirAtten( pBinRendTd, nS, DirAtten_p ) ) != IVAS_ERR_OK ) { return error; } +#ifdef CONF_DISTATT + if ( ( error = TDREND_MIX_SRC_SetDistAtten( pBinRendTd, nS, &DistAtten ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif } } @@ -641,6 +678,9 @@ ivas_error ivas_td_binaural_open_ext( IVAS_OUTPUT_SETUP hTransSetup; ivas_error error; +#ifdef CONF_DISTATT + float *distAtt = NULL; +#endif float *directivity = NULL; if ( inConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) @@ -670,9 +710,16 @@ ivas_error ivas_td_binaural_open_ext( if ( NULL != hRendCfg ) { directivity = hRendCfg->directivity; +#ifdef CONF_DISTATT + distAtt = hRendCfg->distAtt; +#endif } +#ifdef CONF_DISTATT + return ivas_td_binaural_open_unwrap( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity, distAtt, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns ); +#else return ivas_td_binaural_open_unwrap( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns ); +#endif } @@ -762,153 +809,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..cd8b59cf253d440e7f21ac8d1bb5a4a6aea21b5d 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -39,6 +39,9 @@ #include "wmc_auto.h" #include "ivas_rom_rend.h" #include "ivas_rom_binaural_crend_head.h" +#ifdef FIX_989_TD_REND_ROM +#include +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -386,6 +389,9 @@ static ivas_error DefaultBSplineModel( ModelParamsITD_t *modelITD; int16_t i, j; ivas_error error; +#ifdef FIX_989_TD_REND_ROM + float azimSegSamples; +#endif HrFiltSet_p->FilterMethod = TDREND_HRFILT_Method_BSplineModel; model = &( HrFiltSet_p->ModelParams ); @@ -396,6 +402,15 @@ static ivas_error DefaultBSplineModel( model->modelROM = TRUE; /* int16_t parameters */ +#ifdef FIX_989_TD_REND_ROM + 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; +#else model->UseItdModel = 1; model->SplineDegree = 4; model->elevDim2 = 17; @@ -413,6 +428,7 @@ static ivas_error DefaultBSplineModel( model->elevBsStart[3] = 27; model->azimDim2 = defaultHRIR_rom_azimDim2; +#endif model->azimDim3 = defaultHRIR_rom_azimDim3; model->azim_start_idx = defaultHRIR_rom_azim_start_idx; model->azimSegSamples = defaultHRIR_rom_azimSegSamples; @@ -429,10 +445,36 @@ static ivas_error DefaultBSplineModel( } model->azimBsShape[0] = (const float *) defaultHRIR_rom_azimBsShape; +#ifdef FIX_989_TD_REND_ROM + if ( ( model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ) ) == NULL ) +#else if ( ( model->azimKSeq = (float **) malloc( 18 * sizeof( float * ) ) ) == NULL ) +#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); } +#ifdef FIX_989_TD_REND_ROM + for ( i = 0; i < model->elevDim3; i++ ) + { + 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" ) ); + } + if ( model->azimShapeIdx[i] < 0 ) + { + 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; + } + } +#else if ( ( model->azimKSeq[0] = (float *) malloc( 2 * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); @@ -457,6 +499,7 @@ static ivas_error DefaultBSplineModel( model->azimKSeq[i][j] = (float) defaultHRIR_rom_azimSegSamples[0] * j; } } +#endif switch ( output_Fs ) { @@ -465,7 +508,11 @@ 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; +#ifdef FIX_989_TD_REND_ROM + model->K = defaultHRIR_rom_model_configuration[5]; +#else model->K = 128; +#endif if ( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor = 1.0f; @@ -476,7 +523,11 @@ 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; +#ifdef FIX_989_TD_REND_ROM + model->K = (int16_t) ceil( RESAMPLE_FACTOR_32_48 * defaultHRIR_rom_model_configuration[5] ); +#else model->K = 86; +#endif if ( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor = RESAMPLE_FACTOR_32_48; @@ -487,7 +538,11 @@ 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; +#ifdef FIX_989_TD_REND_ROM + model->K = (int16_t) ceilf( RESAMPLE_FACTOR_16_48 * defaultHRIR_rom_model_configuration[5] ); +#else model->K = 43; +#endif if ( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor = RESAMPLE_FACTOR_16_48; @@ -497,6 +552,14 @@ static ivas_error DefaultBSplineModel( break; } +#ifdef FIX_989_TD_REND_ROM + 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; +#else modelITD->N = 4; modelITD->elevDim2 = 20; modelITD->elevDim3 = 18; @@ -511,9 +574,14 @@ static ivas_error DefaultBSplineModel( modelITD->elevBsStart[1] = 4; modelITD->elevBsStart[2] = 11; modelITD->elevBsStart[3] = 21; +#endif modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq; +#ifdef FIX_989_TD_REND_ROM + modelITD->azimBsLen = defaultHRIR_rom_ITD_azimBsLen; + modelITD->azimBsStart = defaultHRIR_rom_ITD_azimBsStart; +#else modelITD->azimBsLen[0] = 11; modelITD->azimBsLen[1] = 21; modelITD->azimBsLen[2] = 31; @@ -524,6 +592,7 @@ static ivas_error DefaultBSplineModel( modelITD->azimBsStart[3] = 63; modelITD->azimSegSamples = 10; +#endif 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..a0f489f35da840da2fe04d569c670a0dd402e0c3 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -51,6 +51,10 @@ 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 ); +#ifdef CONF_DISTATT +static void TDREND_SRC_SPATIAL_SetDistAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DistAtten_t *DistAtten_p ); +#endif + 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 +157,33 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( return IVAS_ERR_OK; } +#ifdef CONF_DISTATT +/*-------------------------------------------------------------------* + * 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; +} +#endif /*-------------------------------------------------------------------* * TDREND_MIX_SRC_SetPlayState() @@ -483,7 +514,27 @@ static void TDREND_SRC_SPATIAL_SetDirAtten( return; } +#ifdef CONF_DISTATT +/*-------------------------------------------------------------------* + * 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; +} +#endif /*-------------------------------------------------------------------* * TDREND_SRC_SPATIAL_GetDirGain() * @@ -557,7 +608,11 @@ static float TDREND_SRC_SPATIAL_GetDistGain( switch ( DistAtten_p->DistAttenModel ) { case TDREND_DIST_ATTEN_MODEL_INV_DIST: +#ifdef CONF_DISTATT + DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); +#else DistGain = DistAtten_p->RefDist / ( DistAtten_p->RefDist + DistAtten_p->RollOffFactor * ( Dist2 - DistAtten_p->RefDist ) ); +#endif break; case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED: @@ -570,8 +625,11 @@ static float TDREND_SRC_SPATIAL_GetDistGain( { Dist2 = DistAtten_p->MaxDist; } - +#ifdef CONF_DISTATT + DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); +#else DistGain = DistAtten_p->RefDist / ( DistAtten_p->RefDist + DistAtten_p->RollOffFactor * ( Dist2 - DistAtten_p->RefDist ) ); +#endif 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..81cf8fc884541170b876d396f23d3d0b60a999c5 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -408,7 +408,11 @@ 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 FIX_1052_EXT_OUTPUT + else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) +#else else +#endif { nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); @@ -418,7 +422,7 @@ int16_t ivas_get_nchan_buffers_dec( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); + nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); } #endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 7de4ed3e8cdc05d65c964f100061f33b45b5cad5..7f557c7f19a95a7e6dd831f0cf854b9a872d2bee 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -77,37 +77,6 @@ int16_t ivas_get_nchan_buffers_dec( const int32_t ivas_total_brate /* i : total IVAS bitrate */ ); -/*----------------------------------------------------------------------------------* - * Limiter prototypes - *----------------------------------------------------------------------------------*/ - - -ivas_error ivas_limiter_open( - IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */ - const int16_t num_channels, /* i : number of I/O channels */ - const int32_t sampling_rate /* i : sampling rate for processing */ -); - -void ivas_limiter_close( - IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ -); - -void ivas_limiter_dec -( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ - const int16_t num_channels, /* i : number of channels to be processed */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const int16_t BER_detect /* i : BER detect flag */ -); - -void limiter_process( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */ - const float threshold, /* i : signal amplitude above which limiting starts to be applied */ - const int16_t BER_detect, /* i : BER detect flag */ - int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ -); /*----------------------------------------------------------------------------------* * TD decorr. function prototypes @@ -665,6 +634,9 @@ 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) */ +#ifdef CONF_DISTATT + const float *distAtt, /* i : Distance attenuation (used for ISM) */ +#endif 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,13 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( const int16_t SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ); - +#ifdef CONF_DISTATT +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 */ +); +#endif ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -980,7 +958,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 +1207,6 @@ void Euler2Quat( IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ ); -float deg2rad( - float degrees -); - float rad2deg( float radians ); @@ -1428,245 +1402,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 @@ -1782,17 +1517,10 @@ void masaPrerendClose( * Split rendering *----------------------------------------------------------------------------------*/ -/* TODO(sgi): Rework interface */ -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -); - ivas_error ivas_td_binaural_renderer_sf_splitBinaural( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[], /* i/o: SCE channels / Binaural synthesis */ - int16_t nSamplesRendered /* i : number of samples to render */ + const int16_t nSamplesRendered /* i : number of samples to render */ ); ivas_error ivas_rend_crendProcessSubframesSplitBin( @@ -1816,8 +1544,8 @@ ivas_error ivas_rend_crendProcessSplitBin( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig, const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], @@ -1858,125 +1586,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..4583d65fd64bb485d546e04a2da3e1848b87a016 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -131,15 +131,26 @@ 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 CONF_DISTATT + ( *hRenderConfig )->distAtt[0] = 15.75f; /* Default max dist */ + ( *hRenderConfig )->distAtt[1] = 1.0f; /* Default ref dist */ + ( *hRenderConfig )->distAtt[2] = 1.0f; /* Default rolloff factor */ +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT ( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k; ( *hRenderConfig )->split_rend_config.dof = 3; ( *hRenderConfig )->split_rend_config.hq_mode = 0; ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *hRenderConfig )->split_rend_config.isar_frame_size_ms = 20; +#endif ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - ( *hRenderConfig )->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - ( *hRenderConfig )->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - ( *hRenderConfig )->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; +#endif #endif return IVAS_ERR_OK; diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 1f791df39c484abd42569ba74715776fb8e7886d..74b3acd3825bcd0ef5cd2cc917e40ed5c3b711b3 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -105,12 +105,14 @@ 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 */ +#ifndef FIX_1053_REVERB_RECONFIGURATION + 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 */ +#endif + 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 */ int16_t do_corr_filter; /* Flag indicating whether correlation filters should be used. */ /* Correlation only supported and needed for binaural playback (i.e. */ @@ -977,7 +979,9 @@ static ivas_error setup_FDN_branches( { int16_t nr_coefs, branch_idx, channel_idx; ivas_error error; +#ifndef FIX_1053_REVERB_RECONFIGURATION float *pCoef_a, *pCoef_b; +#endif error = IVAS_ERR_OK; /* initialize feedback branches */ @@ -999,6 +1003,7 @@ static ivas_error setup_FDN_branches( { for ( branch_idx = 0; branch_idx < pParams->nr_loops; branch_idx++ ) { +#ifndef FIX_1053_REVERB_RECONFIGURATION pCoef_a = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx + nr_coefs]; pCoef_b = &pParams->pT60_filter_coeff[2 * nr_coefs * branch_idx]; @@ -1006,7 +1011,7 @@ static ivas_error setup_FDN_branches( { return error; } - +#endif if ( ( error = set_feedback_delay( hReverb, branch_idx, pParams->pLoop_delays[branch_idx] ) ) != IVAS_ERR_OK ) { return error; @@ -1031,11 +1036,19 @@ static ivas_error setup_FDN_branches( } +#ifdef FIX_1053_REVERB_RECONFIGURATION +/*------------------------------------------------------------------------- + * ivas_reverb_open() + * + * Allocate and initialize FDN reverberation handle + *------------------------------------------------------------------------*/ +#else /*------------------------------------------------------------------------- * ivas_reverb_open() * * Allocate and initialize Crend reverberation handle *------------------------------------------------------------------------*/ +#endif ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ @@ -1045,7 +1058,13 @@ ivas_error ivas_reverb_open( ) { ivas_error error; +#ifdef FIX_1053_REVERB_RECONFIGURATION + REVERB_HANDLE pState = *hReverb; + int16_t nr_coefs, branch_idx; + float *pCoef_a, *pCoef_b; +#else REVERB_HANDLE pState = NULL; +#endif 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,17 +1082,47 @@ ivas_error ivas_reverb_open( predelay_bf_len = output_frame; nr_fc_input = hRenderConfig->roomAcoustics.nBands; +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* 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 " ); + } + } +#else /* Allocate main reverb. handle */ if ( ( pState = (REVERB_HANDLE) malloc( sizeof( REVERB_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Reverberator " ); } +#endif if ( ( error = set_base_config( ¶ms, output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + /* Allocate memory for feedback delay lines */ + for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) + { + 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, "Cannot allocate memory for FDN Reverberator" ); + } + } +#else /* Allocate memory for feedback delay lines */ for ( loop_idx = 0; loop_idx < IVAS_REV_MAX_NR_BRANCHES; loop_idx++ ) { @@ -1088,20 +1137,26 @@ ivas_error ivas_reverb_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CREND Reverberator" ); } +#endif 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. */ +#ifndef FIX_1053_REVERB_RECONFIGURATION 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; +#endif 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]; +#ifndef FIX_1053_REVERB_RECONFIGURATION params.pHrtf_inter_aural_coherence = &pState->fft_filter_color_1.fft_spectrum[0]; +#endif /* 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 +1187,15 @@ ivas_error ivas_reverb_open( } /* set up input downmix */ +#ifdef FIX_1053_REVERB_RECONFIGURATION + if ( *hReverb == NULL ) + { + pState->dmx_gain = calc_dmx_gain(); + } +#else + /* set up input downmix */ pState->dmx_gain = calc_dmx_gain(); +#endif /* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */ calc_predelay( ¶ms, hRenderConfig->roomAcoustics.acousticPreDelay, output_Fs ); @@ -1156,7 +1219,20 @@ 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 ); +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* === Copy parameters from ivas_reverb_params_t into DSP blocks === */ + /* === to be used for subsequent audio signal processing === */ + if ( *hReverb == NULL ) + { + 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; + } + } +#else /* === Now, copy parameters from ivas_reverb_params_t into DSP blocks === */ /* === to be used for subsequent audio signal processing === */ @@ -1167,6 +1243,7 @@ ivas_error ivas_reverb_open( { return error; } +#endif if ( pState->do_corr_filter ) { @@ -1199,6 +1276,36 @@ ivas_error ivas_reverb_open( return error; } +#ifdef FIX_1053_REVERB_RECONFIGURATION + 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 ) + { + return error; + } + } + else + { + 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; + } + } +#else /* init predelay */ ivas_rev_delay_line_init( &( pState->predelay_line ), pState->pPredelay_buffer, params.pre_delay, predelay_bf_len ); @@ -1207,6 +1314,7 @@ ivas_error ivas_reverb_open( { return error; } +#endif *hReverb = pState; diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c index 2879476014732b60dd705370ceabaee7a76aff8e..706d7de2d2972eb8c2cb4ccd5987630702c03d41 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer.c @@ -50,9 +50,26 @@ *------------------------------------------------------------------------*/ /* TD renderer default HRIR model */ const float defaultHRIR_rom_latency_s = 0.000020834f; +#ifdef FIX_989_TD_REND_ROM +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, +}; +#else const int16_t defaultHRIR_rom_azimDim2[15] = { 1, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 1, }; +#endif const int16_t defaultHRIR_rom_azimDim3[15] = { 1, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 1, }; @@ -10139,6 +10156,26 @@ 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, }; +#ifdef FIX_989_TD_REND_ROM +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, +}; +#endif 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..f633f06a686dc5f0614908498d1ce6fcbe369ab0 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.h +++ b/lib_rend/ivas_rom_TdBinauralRenderer.h @@ -47,7 +47,11 @@ *------------------------------------------------------------------------*/ /* TD renderer default HRIR model */ extern const float defaultHRIR_rom_latency_s; +#ifdef FIX_989_TD_REND_ROM +extern const int16_t defaultHRIR_rom_model_configuration[6]; +#else extern const int16_t defaultHRIR_rom_azimDim2[15]; +#endif 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 +70,10 @@ 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]; +#ifdef FIX_989_TD_REND_ROM +extern const int16_t defaultHRIR_rom_elevBsLen[4]; +extern const int16_t defaultHRIR_rom_elevBsStart[4]; +#endif 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 +81,11 @@ 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]; +#ifdef FIX_989_TD_REND_ROM +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 #endif diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index e39c43813781e3fe9274c4f99a256e00f7c676bc..9988962dbe62b3e3b8f10d54b735357bcc328701 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -137,12 +137,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..46814b435b2b998aa699a862b2c84d4efa3b39ca 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -37,6 +37,7 @@ #include #include "cnst.h" #include "prot.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #ifdef DEBUGGING #include "debug.h" @@ -52,7 +53,7 @@ static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ #endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); @@ -186,100 +187,6 @@ void QuatToRotMat( } -/*------------------------------------------------------------------------- - * Euler2Quat() - * - * Calculate corresponding Quaternion from Euler angles in radians - *------------------------------------------------------------------------*/ - -void Euler2Quat( - const float yaw, /* i : yaw (x) */ - const float pitch, /* i : pitch (y) */ - const float roll, /* i : roll (z) */ - IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ -) -{ - float cr = cosf( roll * 0.5f ); - float sr = sinf( roll * 0.5f ); - float cp = cosf( pitch * 0.5f ); - float sp = sinf( pitch * 0.5f ); - float cy = cosf( yaw * 0.5f ); - float sy = sinf( yaw * 0.5f ); - quat->w = cr * cp * cy + sr * sp * sy; - quat->x = sr * cp * cy - cr * sp * sy; - quat->y = sr * cp * sy + cr * sp * cy; - quat->z = cr * cp * sy - sr * sp * cy; - - return; -} - - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*------------------------------------------------------------------------- - * Quat2EulerDegree() - * - * Quaternion handling: calculate corresponding Euler angles in degrees - *------------------------------------------------------------------------*/ - -void Quat2EulerDegree( - const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ - float *yaw, /* o : yaw */ - float *pitch, /* o : pitch */ - float *roll /* o : roll */ -) -{ - if ( quat.w != -3.0 ) - { - float p; - *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) ); - p = 2 * ( quat.w * quat.y - quat.z * quat.x ); - p = max( -1.0f, min( 1.0f, p ) ); - *pitch = asinf( p ); - *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) ); - *yaw *= _180_OVER_PI; - *pitch *= _180_OVER_PI; - *roll *= _180_OVER_PI; - } - else - { - /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention - * - * yaw: rotate scene counter-clockwise in the horizontal plane - * pitch: rotate scene in the median plane, increase elevation with positive values - * roll: rotate scene from the right ear to the top - */ - *yaw = quat.z; - *pitch = quat.y; - *roll = quat.x; - } - - return; -} -#endif - - -/*------------------------------------------------------------------------- - * deg2rad() - * - * Converts degrees to normalized radians - *------------------------------------------------------------------------*/ - -float deg2rad( - float degrees ) -{ - while ( degrees >= 180.0f ) - { - degrees = degrees - 360.0f; - } - while ( degrees <= -180.0f ) - { - degrees = degrees + 360.0f; - } - - return PI_OVER_180 * degrees; -} - - /*------------------------------------------------------------------------- * rad2deg() * @@ -995,7 +902,7 @@ ivas_error combine_external_and_head_orientations_dec( ) { #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif IVAS_QUATERNION *pHeadRotQuaternion = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -1036,7 +943,7 @@ ivas_error combine_external_and_head_orientations_rend( ) { #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -1087,7 +994,7 @@ ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ #endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ diff --git a/lib_rend/ivas_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..d1f0fe4bca2b805fb03721aae9767df554c983ee 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,9 @@ typedef struct ivas_binaural_reverb_struct uint32_t binRend_RandNext; int16_t highestBinauralCoherenceBin; +#ifndef FIX_1053_REVERB_RECONFIGURATION float dmxmtx[BINAURAL_CHANNELS][MAX_OUTPUT_CHANNELS]; +#endif float foa_enc[MAX_OUTPUT_CHANNELS][FOA_CHANNELS]; } REVERB_STRUCT, *REVERB_STRUCT_HANDLE; @@ -640,7 +637,7 @@ typedef struct EFAP } EFAP, *EFAP_HANDLE; /*----------------------------------------------------------------------------------* - * Orientation tracking structure + * Head rotation data structure *----------------------------------------------------------------------------------*/ typedef struct ivas_orient_trk_state_t @@ -657,18 +654,14 @@ 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]; + 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]; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif ivas_orient_trk_state_t *hOrientationTracker; @@ -692,30 +685,11 @@ typedef struct ivas_binaural_head_track_struct ivas_orient_trk_state_t *OrientationTracker; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; -/*----------------------------------------------------------------------------------* - * 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]; @@ -741,7 +715,7 @@ typedef struct ivas_combined_orientation_struct int16_t shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; int16_t sr_low_res_flag; #endif IVAS_QUATERNION Quaternion_frozen_ext; @@ -756,6 +730,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 +828,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 +924,28 @@ 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 modelROM; /* Flag that indicates that the model resides in ROM (controls init/dealloc). */ + int16_t UseItdModel; /* Controls whether ITD model is used. */ +#ifdef FIX_989_TD_REND_ROM + int16_t K; /* Length of filter */ +#else int16_t SplineDegree; /* Degree of the spline functions */ int16_t K; /* Length of filter */ int16_t elevDim2; +#endif int16_t elevDim3; int16_t AlphaN; /* Number of rows in Alpha matrices */ int16_t num_unique_azim_splines; int16_t elevSegSamples; +#ifdef FIX_989_TD_REND_ROM + const int16_t *elevBsLen; + const int16_t *elevBsStart; +#else int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; const int16_t *azimDim2; +#endif const int16_t *azimDim3; const int16_t *azim_start_idx; const int16_t *azimSegSamples; @@ -975,7 +972,12 @@ typedef struct float *ER_dyn; float *elevBsShape_dyn; float *elevKSeq_dyn; +#ifdef FIX_989_TD_REND_ROM + int16_t *elevBsLen_dyn; + int16_t *elevBsStart_dyn; +#else int16_t *azimDim2_dyn; +#endif int16_t *azimDim3_dyn; int16_t *azim_start_idx_dyn; int16_t *azimSegSamples_dyn; @@ -987,6 +989,13 @@ typedef struct typedef struct { +#ifdef FIX_989_TD_REND_ROM + int16_t elevDim3; + const float *elevKSeq; /* Array, length elevDim3-2 */ + int16_t azimDim3; + const float *azimKSeq; /* Array, length azimDim3-2 */ + const float *W; /* Array, size (elevDim3*azimDim3) x K */ +#else int16_t N; /* Polynomial degree */ int16_t elevDim2; @@ -996,14 +1005,25 @@ typedef struct int16_t azimDim3; const float *azimKSeq; /* Array, length azimDim3-2 */ const float *W; /* Array, size (elevDim3*azimDim3) x K */ +#endif +#ifdef FIX_989_TD_REND_ROM + const int16_t *azimBsLen; + const int16_t *azimBsStart; +#else int16_t azimBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; int16_t azimBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; +#endif const float *azimBsShape; int16_t azimSegSamples; +#ifdef FIX_989_TD_REND_ROM + const int16_t *elevBsLen; + const int16_t *elevBsStart; +#else int16_t elevBsLen[HRTF_MODEL_BSPLINE_NUM_COEFFS]; int16_t elevBsStart[HRTF_MODEL_BSPLINE_NUM_COEFFS]; +#endif const float *elevBsShape; int16_t elevSegSamples; float resamp_factor; @@ -1014,6 +1034,12 @@ typedef struct float *W_dyn; float *azimBsShape_dyn; float *elevBsShape_dyn; +#ifdef FIX_989_TD_REND_ROM + int16_t *azimBsLen_dyn; + int16_t *azimBsStart_dyn; + int16_t *elevBsLen_dyn; + int16_t *elevBsStart_dyn; +#endif } ModelParamsITD_t; @@ -1367,20 +1393,20 @@ typedef struct ivas_split_rend_huffman_cfg_t typedef struct ivas_binaural_head_rot_split_rendering_huff_struct { ivas_split_rend_huffman_cfg_t pred[2]; - int16_t pred_idx_trav[2][IVAS_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; int16_t pred_base2_code_len[2]; ivas_split_rend_huffman_cfg_t pred_roll; - int16_t pred_roll_idx_trav[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; int16_t pred_roll_base2_code_len; ivas_split_rend_huffman_cfg_t gd; int16_t gd_base2_code_len; - int16_t gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; ivas_split_rend_huffman_cfg_t p_gd; int16_t p_gd_base2_code_len; - int16_t p_gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; ivas_split_rend_huffman_cfg_t p_gd_diff; int16_t p_gd_diff_base2_code_len; - int16_t p_gd_diff_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; } BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; @@ -1392,7 +1418,7 @@ typedef struct ivas_binaural_head_rot_split_post_rendering_struct int16_t low_Res; float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; BIN_HR_SPLIT_REND_HUFF huff_cfg; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -1416,7 +1442,7 @@ 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]; + 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]; @@ -1448,10 +1474,7 @@ typedef struct { float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; -#if CLDFB_PLC_XF > 0 float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; -#endif - } CLDFB_PLC, *CLDFB_PLC_HANDLE; typedef struct @@ -1459,6 +1482,7 @@ typedef struct CLDFB_PLC CldfbPLC_state; int16_t prev_bfi; int16_t bf_count; + int16_t iNumSubSets; } SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE; @@ -1479,50 +1503,6 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct } BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; -typedef struct -{ -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; -#else - HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; -#endif - HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; - -} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; - -typedef struct -{ - int16_t num_poses; - float relative_head_poses[MAX_HEAD_ROT_POSES][3]; - int16_t dof; - int16_t hq_mode; - IVAS_SPLIT_REND_ROT_AXIS rot_axis; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; - -} MULTI_BIN_REND_POSE_DATA; - -typedef struct -{ - MULTI_BIN_REND_POSE_DATA multiBinPoseData; - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; - BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; - CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; - IVAS_LC3PLUS_ENC_HANDLE hLc3plusEnc; - BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; - float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ - int32_t lc3plusDelaySamples; - -} SPLIT_REND_WRAPPER; - -typedef struct -{ - MULTI_BIN_REND_POSE_DATA multiBinPoseData; - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; - int16_t first_good_frame_received; - IVAS_LC3PLUS_DEC_HANDLE hLc3plusDec; - -} SPLIT_POST_REND_WRAPPER; #endif diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a6ddac23a9ccd562ac7b1b3671447f9a3479ff86..b99bf9a93ad001bcbf97920ddb4c0a904b762ce6 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#include "isar_prot.h" +#include "isar_stat.h" +#include "lib_isar_pre_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" @@ -48,30 +51,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 *-------------------------------------------------------------------*/ @@ -201,18 +184,6 @@ typedef struct DIRAC_ANA_HANDLE hDirAC; } input_sba; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef struct -{ - input_base base; - SPLIT_POST_REND_WRAPPER splitPostRendWrapper; - float *bufferData; - int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ - IVAS_REND_BitstreamBuffer *hBits; -} input_split_post_rend; -#endif - - typedef struct { input_base base; @@ -245,9 +216,6 @@ struct IVAS_REND input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; -#endif AUDIO_CONFIG inputConfig; AUDIO_CONFIG outputConfig; @@ -282,6 +250,20 @@ static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderSbaToMultiBinauralCldfb( + input_sba *sbaInput, + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot, + const int16_t num_subframes ); + +static ivas_error renderSbaToMultiBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + float out[][L_FRAME48k] ); +#endif + /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -356,7 +338,7 @@ static float *getSmplPtr( #ifdef SPLIT_REND_WITH_HEAD_ROT static void convertBitsBufferToInternalBitsBuff( const IVAS_REND_BitstreamBuffer outBits, - IVAS_SPLIT_REND_BITS_HANDLE hBits ) + ISAR_SPLIT_REND_BITS_HANDLE hBits ) { hBits->bits_buf = outBits.bits; hBits->bits_read = outBits.config.bitsRead; @@ -371,7 +353,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; @@ -2630,35 +2612,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, @@ -2691,7 +2644,7 @@ static ivas_error updateSbaPanGains( case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: { - if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { assert( inConfig == IVAS_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" ); @@ -2713,7 +2666,7 @@ static ivas_error updateSbaPanGains( #endif case IVAS_AUDIO_CONFIG_BINAURAL: #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { @@ -2770,52 +2723,6 @@ static ivas_error updateSbaPanGains( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error setRendInputActiveSplitPostRend( - void *input, - const AUDIO_CONFIG inConfig, - const IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRendCfg, -#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 ) @@ -2908,38 +2815,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 ) { @@ -3040,62 +2915,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() @@ -3191,7 +3010,7 @@ ivas_error IVAS_REND_Open( /* Initialize inputs */ #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_init_split_rend_handles( &hIvasRend->splitRendWrapper ); + isar_init_split_rend_handles( &hIvasRend->splitRendWrapper ); hIvasRend->splitRendEncBuffer.data = NULL; #endif @@ -3260,19 +3079,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 +3362,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 +3427,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; } @@ -3731,7 +3519,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,24 +3528,66 @@ static int16_t getCldfbRendFlag( return isCldfbRend; } +/*------------------------------------------------------------------------- + * Function ivas_pre_rend_init() + * + * + *------------------------------------------------------------------------*/ -static void closeSplitRend( +static ivas_error ivas_pre_rend_init( SPLIT_REND_WRAPPER *pSplitRendWrapper, - IVAS_REND_AudioBuffer *pSplitRendEncBuffer ) + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t cldfb_in_flag, + const int16_t num_subframes ) { - ivas_split_renderer_close( pSplitRendWrapper ); + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; - if ( pSplitRendEncBuffer->data != NULL ) + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - free( pSplitRendEncBuffer->data ); - pSplitRendEncBuffer->data = NULL; + if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + ISAR_PRE_REND_GetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + else if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + isar_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } + + if ( ( error = ISAR_PRE_REND_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*allocate for CLDFB in and change to TD during process if needed*/ + bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; + bufConfig.is_cldfb = 1; + pSplitRendEncBuffer->config = bufConfig; + + if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } } + else + { + IVAS_REND_AudioBufferConfig bufConfig2; - pSplitRendEncBuffer->config.numChannels = 0; - pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data = NULL; + } - return; + return IVAS_ERR_OK; } + #endif @@ -3792,12 +3622,7 @@ ivas_error IVAS_REND_AddInput( int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, 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; } @@ -3830,14 +3655,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; } @@ -4106,11 +3923,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; } @@ -4236,7 +4048,7 @@ ivas_error IVAS_REND_GetDelay( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( hIvasRend->splitRendWrapper.hBinHrSplitPreRend != NULL ) { - if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; } @@ -4261,31 +4073,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 ) @@ -4591,10 +4378,16 @@ int16_t IVAS_REND_GetRenderConfig( hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; hRCout->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.isar_frame_size_ms = 20; +#endif hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.lc3plus_highres = 0; +#endif #endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; @@ -4616,8 +4409,17 @@ int16_t IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef FIX_1053_REVERB_RECONFIGURATION + uint16_t i; + input_ism *pIsmInput; + input_masa *pMasaInput; + input_mc *pMcInput; + input_sba *pSbaInput; + ivas_error error; +#else #ifdef SPLIT_REND_WITH_HEAD_ROT ivas_error error; +#endif #endif if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) @@ -4649,17 +4451,157 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } +#ifdef FIX_1053_REVERB_RECONFIGURATION + /* Re-initialize reverb instance if already available */ + /* ISM inputs */ + for ( i = 0, pIsmInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pIsmInput ) + { + 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; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend[0] != NULL ) +#else + if ( pIsmInput->crendWrapper != NULL && pIsmInput->crendWrapper->hCrend != NULL ) +#endif + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_reverb_open( &pIsmInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pIsmInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + + /* MASA inputs */ + for ( i = 0, pMasaInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pMasaInput ) + { + if ( pMasaInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMasaInput->hMasaExtRend != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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; + } + } +#else + if ( pMasaInput->hMasaExtRend->hDiracDecBin != NULL && pMasaInput->hMasaExtRend->hDiracDecBin->hReverb != NULL ) + { + ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin->hReverb ); + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin->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; + } + } +#endif + 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; + } + } + } + } + + /* Multi-channel inputs */ + for ( i = 0, pMcInput = hIvasRend->inputsMc; i < RENDERER_MAX_MC_INPUTS; ++i, ++pMcInput ) + { + if ( pMcInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( pMcInput->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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; + } + } +#else + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend && pMcInput->crendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + + /* 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; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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; + } + } +#else + if ( pSbaInput->crendWrapper != NULL && pSbaInput->crendWrapper->hCrend != NULL && pSbaInput->crendWrapper->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &pSbaInput->crendWrapper->hCrend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pSbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } +#endif + #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; } hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; - if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -4670,14 +4612,9 @@ int16_t IVAS_REND_FeedRenderConfig( { int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + ISAR_PRE_REND_close( &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 ) - { - 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; } @@ -4688,42 +4625,6 @@ int16_t IVAS_REND_FeedRenderConfig( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-------------------------------------------------------------------* - * IVAS_REND_FeedSplitBinauralBitstream() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_REND_FeedSplitBinauralBitstream( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ -) -{ - ivas_error error; - input_base *inputBase; - input_split_post_rend *inputSplitPostRend; - - /* Validate function arguments */ - if ( hIvasRend == NULL || hBits == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) - { - return error; - } - - inputSplitPostRend = (input_split_post_rend *) inputBase; - inputSplitPostRend->hBits = hBits; - - return IVAS_ERR_OK; -} -#endif - - /*-------------------------------------------------------------------* * IVAS_REND_SetHeadRotation() * @@ -4735,7 +4636,7 @@ ivas_error IVAS_REND_SetHeadRotation( const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ #ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ #endif const int16_t sf_idx /* i : subframe index */ ) @@ -5837,7 +5738,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 ) { @@ -6536,7 +6437,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 ) { @@ -6798,331 +6699,6 @@ static void renderSbaToSba( } #ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error splitBinLc3plusDecode( - SPLIT_POST_REND_WRAPPER *hSplitBin, - IVAS_SPLIT_REND_BITS_HANDLE bits, - float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k], - IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction ) -{ - ivas_error error; - float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; - int32_t lc3plusBitrateId, lc3plusBitstreamSize; - - push_wmops( "splitBinLc3plusDecode" ); - assert( hSplitBin->hLc3plusDec != NULL ); - - /* Find next byte boundary */ - while ( bits->bits_read % 8 != 0 ) - { - ++bits->bits_read; - } - /* Read LC3plus bitstream size info */ - lc3plusBitrateId = ivas_split_rend_bitstream_read_int32( bits, 8 ); - lc3plusBitstreamSize = ivas_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); - - for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) - { - channel_ptrs[i] = outputBuffer[i]; - } - - if ( ( error = IVAS_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) - { - return error; - } - - pop_wmops(); - return IVAS_ERR_OK; -} - - -static ivas_error renderSplitBinauralWithPostRot( - input_split_post_rend *splitBinInput, - IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI ) -{ - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - ivas_error error; - float Cldfb_RealBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural_5ms[MAX_PARAM_SPATIAL_SUBFRAMES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t sf_idx, ch_idx; - IVAS_SPLIT_REND_BITS_DATA bits; - float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; - COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; - SPLIT_POST_REND_WRAPPER *hSplitBin; - int8_t isPostRendInputCldfb; - int16_t chnlIdx, slotIdx, smplIdx; - int16_t preRendFrameSize_ms; - int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; - int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; - float *readPtr, *writePtr; - 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 +6724,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++ ) { @@ -7223,7 +6799,6 @@ static ivas_error renderSbaToMultiBinaural( return IVAS_ERR_OK; } - static ivas_error renderSbaToMultiBinauralCldfb( input_sba *sbaInput, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], @@ -7259,7 +6834,7 @@ static ivas_error renderSbaToSplitBinaural( push_wmops( "renderSbaToSplitBinaural" ); error = IVAS_ERR_OK; - if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { if ( ( renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) @@ -7301,7 +6876,7 @@ static ivas_error renderSbaToBinaural( push_wmops( "renderSbaToBinaural" ); #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -7490,39 +7065,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 ) @@ -7610,34 +7152,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 ) @@ -8161,7 +7675,7 @@ 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_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 */ @@ -8268,7 +7782,7 @@ static ivas_error getSamplesInternal( int16_t num_poses_orig; num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; outAudio = hIvasRend->splitRendEncBuffer; - ivas_renderSplitGetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); /* Clear output buffer for split rendering bitstream */ @@ -8296,13 +7810,7 @@ static ivas_error getSamplesInternal( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) - { - return error; - } -#else - +#ifndef SPLIT_REND_WITH_HEAD_ROT #ifndef DISABLE_LIMITER #ifdef DEBUGGING hIvasRend->numClipping += @@ -8310,11 +7818,10 @@ static ivas_error getSamplesInternal( limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); #endif #endif - #ifdef SPLIT_REND_WITH_HEAD_ROT if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - IVAS_SPLIT_REND_BITS_DATA bits; + ISAR_SPLIT_REND_BITS_DATA bits; int16_t cldfb_in_flag; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -8351,8 +7858,23 @@ 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, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms, +#endif + hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, + &bits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), + tmpBinaural, + 1, + cldfb_in_flag, + ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, + ro_md_flag ) ) != IVAS_ERR_OK ) { return error; } @@ -8425,7 +7947,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; } @@ -8440,28 +7962,30 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( return getSamplesInternal( hIvasRend, outAudio, hBits ); } - -/*-------------------------------------------------------------------* - * IVAS_REND_GetSplitBinauralSamples() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_REND_GetSplitBinauralSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ - bool *needNewFrame ) +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ +#endif +) { - ivas_error error; - - if ( ( error = getSamplesInternal( hIvasRend, outAudio, NULL ) ) != IVAS_ERR_OK ) + if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; - + *pCodec = hIvasRend->hRendererConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + *pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms; +#endif + *poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode; return IVAS_ERR_OK; } + #endif @@ -8507,12 +8031,6 @@ void IVAS_REND_Close( { clearInputMasa( &hIvasRend->inputsMasa[i] ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); - } -#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); @@ -8521,7 +8039,7 @@ void IVAS_REND_Close( #ifdef SPLIT_REND_WITH_HEAD_ROT /* Split binaural rendering */ - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); #endif closeHeadRotation( hIvasRend ); diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index a670e75af2108c83450e4066dea57a2c43769b23..768a53cfa52e2d0126961a7eb11032c16a00f727 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -35,6 +35,7 @@ #include "common_api_types.h" #include +#include "ivas_stat_rend.h" /*---------------------------------------------------------------------* * Renderer constants @@ -45,10 +46,6 @@ #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_MAX_INPUT_LFE_CHANNELS 4 -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define RENDERER_MAX_BIN_INPUTS 1 -#endif - /*---------------------------------------------------------------------* * Renderer structures @@ -56,30 +53,19 @@ typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; -typedef struct -{ - int16_t numSamplesPerChannel; - int16_t numChannels; -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t is_cldfb; -#endif -} IVAS_REND_AudioBufferConfig; - -typedef struct -{ - IVAS_REND_AudioBufferConfig config; - float *data; -} IVAS_REND_AudioBuffer; - #ifdef SPLIT_REND_WITH_HEAD_ROT typedef struct { int32_t bufLenInBytes; int32_t bitsWritten; int32_t bitsRead; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; +#endif } IVAS_REND_BitstreamBufferConfig; typedef struct { @@ -125,13 +111,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 */ @@ -284,6 +270,17 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ ); + +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ +#endif +); #endif ivas_error IVAS_REND_SetHeadRotation( @@ -291,7 +288,7 @@ ivas_error IVAS_REND_SetHeadRotation( const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ #ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ #endif const int16_t sf_idx /* i : subframe index */ ); @@ -381,8 +378,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 */ diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 813a3dfc27c32c2a3082ca8249920f5aac2e6908..3f0393752566159ec4c1f4d82d27942d07c288f9 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,6 +269,15 @@ static void LoadBSplineBinaryITD( ) { int16_t tmp; +#ifdef FIX_989_TD_REND_ROM + 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->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 ); +#else 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 ); @@ -259,14 +288,22 @@ static void LoadBSplineBinaryITD( 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 ); +#endif fread( &tmp, sizeof( int16_t ), 1, f_hrtf ); modelITD->W_dyn = (float *) malloc( tmp * sizeof( float ) ); fread( modelITD->W_dyn, sizeof( float ), tmp, f_hrtf ); /* azimuth */ +#ifdef FIX_989_TD_REND_ROM + 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 ); +#else 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 ); +#endif fread( &tmp, sizeof( int16_t ), 1, f_hrtf ); @@ -276,8 +313,15 @@ static void LoadBSplineBinaryITD( fread( &modelITD->azimSegSamples, sizeof( int16_t ), 1, f_hrtf ); /* elevation */ +#ifdef FIX_989_TD_REND_ROM + 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 ); +#else 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 ); +#endif fread( &tmp, sizeof( int16_t ), 1, f_hrtf ); @@ -291,6 +335,12 @@ static void LoadBSplineBinaryITD( modelITD->W = (const float *) modelITD->W_dyn; modelITD->azimBsShape = (const float *) modelITD->azimBsShape_dyn; modelITD->elevBsShape = (const float *) modelITD->elevBsShape_dyn; +#ifdef FIX_989_TD_REND_ROM + 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; +#endif return; } @@ -347,6 +397,12 @@ static ivas_error LoadBSplineBinary( return IVAS_ERROR( IVAS_ERR_INVALID_HRTF, "Error: HR filter file had an unsupported sampling rate (%d kHz)", tmp ); } +#ifdef FIX_989_TD_REND_ROM + fread( &model->K, 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 ); +#else fread( &model->SplineDegree, sizeof( int16_t ), 1, f_hrtf ); fread( &model->K, sizeof( int16_t ), 1, f_hrtf ); @@ -355,12 +411,15 @@ static ivas_error LoadBSplineBinary( 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 ) ); +#endif 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++ ) { +#ifndef FIX_989_TD_REND_ROM fread( &model->azimDim2_dyn[i], sizeof( int16_t ), 1, f_hrtf ); +#endif 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 +452,15 @@ static ivas_error LoadBSplineBinary( fread( model->azimShapeSampFactor_dyn, sizeof( int16_t ), model->elevDim3, f_hrtf ); /* elevation */ +#ifdef FIX_989_TD_REND_ROM + 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 ); +#else 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 ); +#endif 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 +472,15 @@ 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; +#ifdef FIX_989_TD_REND_ROM + model->elevBsLen = (const int16_t *) model->elevBsLen_dyn; + model->elevBsStart = (const int16_t *) model->elevBsStart_dyn; +#endif model->elevBsShape = (const float *) model->elevBsShape_dyn; model->elevKSeq = (const float *) model->elevKSeq_dyn; +#ifndef FIX_989_TD_REND_ROM model->azimDim2 = (const int16_t *) model->azimDim2_dyn; +#endif 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 +528,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 +572,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 +611,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 +691,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 +739,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 +896,18 @@ void destroy_td_hrtf( free( ( *hHrtf )->ModelParamsITD.W_dyn ); free( ( *hHrtf )->ModelParamsITD.azimBsShape_dyn ); free( ( *hHrtf )->ModelParamsITD.elevBsShape_dyn ); +#ifdef FIX_989_TD_REND_ROM + free( ( *hHrtf )->ModelParamsITD.azimBsLen_dyn ); + free( ( *hHrtf )->ModelParamsITD.azimBsStart_dyn ); + free( ( *hHrtf )->ModelParamsITD.elevBsLen_dyn ); + free( ( *hHrtf )->ModelParamsITD.elevBsStart_dyn ); +#endif } free( ( *hHrtf )->ModelParams.elevKSeq_dyn ); free( ( *hHrtf )->ModelParams.azim_start_idx_dyn ); +#ifndef FIX_989_TD_REND_ROM free( ( *hHrtf )->ModelParams.azimDim2_dyn ); +#endif free( ( *hHrtf )->ModelParams.azimDim3_dyn ); free( ( *hHrtf )->ModelParams.AlphaL_dyn ); free( ( *hHrtf )->ModelParams.AlphaR_dyn ); @@ -788,6 +915,10 @@ void destroy_td_hrtf( free( ( *hHrtf )->ModelParams.azimShapeIdx_dyn ); free( ( *hHrtf )->ModelParams.azimShapeSampFactor_dyn ); +#ifdef FIX_989_TD_REND_ROM + free( ( *hHrtf )->ModelParams.elevBsLen_dyn ); + free( ( *hHrtf )->ModelParams.elevBsStart_dyn ); +#endif free( ( *hHrtf )->ModelParams.elevBsShape_dyn ); for ( i = 0; i < ( *hHrtf )->ModelParams.num_unique_azim_splines; i++ ) @@ -829,7 +960,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 +1075,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 +1132,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,169 +1188,1023 @@ 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( - 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 */ +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; + 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; - ( *hHRTF )->allocate_init_flag = 0; - - if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV ) + if ( *hHRTF == NULL ) { - if ( ( error = ivas_allocate_binaural_hrtf( *hHRTF, 0, input_cfg, RENDERER_BINAURAL_FASTCONV, ( *hHRTF )->allocate_init_flag ) ) != IVAS_ERR_OK ) + if ( ( ( *hHRTF ) = (HRTFS_HANDLE) malloc( sizeof( HRTFS_DATA ) ) ) == NULL ) { - return error; + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF binary data\n" ); } - } - 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 ) + + if ( ( error = ivas_hrtf_init( *hHRTF ) ) != IVAS_ERR_OK ) { return error; } } else { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "renderer type not compliant" ); + return IVAS_ERR_INTERNAL; } + ( *hHRTF )->init_from_rom = 0; 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 ); + /* latency_s Q factor*/ + factorQ = *( (Word16 *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( Word16 ); - 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 ); + /* latency_s */ + ( *hHRTF )->latency_s = (float) ( *( (Word32 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * (float) factorQ ); + hrtf_data_rptr += sizeof( Word32 ); - 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 ); + /* max_num_ir */ + ( *hHRTF )->max_num_ir = *( (uint16_t *) ( hrtf_data_rptr ) ); + 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 ); + /* 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 ); - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + /* 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++ ) { - 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 ); - } + ( *hHRTF )->num_iterations[i][j] = *( (uint16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint16_t ); } - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + } + + /* pIndex_frequency_max */ + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { - for ( j = 0; j < HRTF_LS_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 ) { - memcpy( ( *hHRTF )->leftHRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + 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; } - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + } + + /* 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++ ) { - for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) - { - memcpy( ( *hHRTF )->rightHRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); - } + ( *hHRTF )->num_iterations_diffuse[j] = *( (uint16_t *) ( hrtf_data_rptr ) ); + hrtf_data_rptr += sizeof( uint16_t ); } - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + + /* pIndex_frequency_max_diffuse (the size depends on num_iterations_diffuse) */ + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { - for ( j = 0; j < HRTF_LS_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 ) { - memcpy( ( *hHRTF )->rightHRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + 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; } } - else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) + + /* 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++ ) { - /* HRIR_HOA3 */ - ( *hHRTF )->FASTCONV_HOA3_latency_s = *( (float *) ( hrtf_data_rptr ) ); - hrtf_data_rptr += sizeof( float ); + ( *hHRTF )->inv_diffuse_weight[0][i] = (float) ( *( (Word16 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * factorQ ); + hrtf_data_rptr += sizeof( Word16 ); + } - 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 ); + 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 ); + } - 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 ); + /* 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 ); - 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 ); - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + /* 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++ ) { - for ( j = 0; j < HOA3_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 ) { - memcpy( ( *hHRTF )->leftHRIRReal_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for Out_to_bin_re" ); } - } - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) - { - for ( j = 0; j < HOA3_CHANNELS; j++ ) + 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++ ) { - memcpy( ( *hHRTF )->leftHRIRImag_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + 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]; } } - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + } + + /* 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++ ) { - for ( j = 0; j < HOA3_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 ) { - memcpy( ( *hHRTF )->rightHRIRReal_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for Out_to_bin_im" ); } - } - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) - { - for ( j = 0; j < HOA3_CHANNELS; j++ ) + 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++ ) { - memcpy( ( *hHRTF )->rightHRIRImag_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); - hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + 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]; } } } - else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) - { - /* HRIR_HOA2 */ - ( *hHRTF )->FASTCONV_HOA2_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 ); + /* 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 ( HOA2_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "HRTF binary file not compliant (HOA2_CHANNELS)" ); + 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, k; + char *hrtf_data_rptr; + ivas_error error; + Word16 factorQ; + int32_t *ptW32; + int16_t *ptW16; + + ( *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 ) + { + /* 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 ) ) ) + { + 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 ); + + /* 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; 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++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->leftHRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->rightHRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->rightHRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + } + } + } + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) + { + /* HRIR_HOA3 */ + ( *hHRTF )->FASTCONV_HOA3_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 ( 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 ); + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->leftHRIRReal_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->leftHRIRImag_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->rightHRIRReal_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + } + } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) + { + for ( j = 0; j < HOA3_CHANNELS; j++ ) + { + memcpy( ( *hHRTF )->rightHRIRImag_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + } + } + } + else if ( rend_type == HRTF_READER_RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) + { + /* HRIR_HOA2 */ + ( *hHRTF )->FASTCONV_HOA2_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 ( 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 ); @@ -1403,6 +2398,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 +2427,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 +2445,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 +2574,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 +2605,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 +2626,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 +2663,6 @@ ivas_error load_parambin_HRTF_from_binary( } } - /*---------------------------------------------------------------------* * create_SetOfHRTF_from_binary() * @@ -1647,6 +2682,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 +2714,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 +2763,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 +2921,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..ef398017ff1ec818c86d7d68875af78f2ec61aeb 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -124,6 +124,9 @@ struct RenderConfigReader AcousticEnv *pAE; /* Acoustic environments */ uint32_t nDP; /* Number of directivity patterns */ DirectrivityPat *pDP; /* Directivity Pattern */ +#ifdef CONF_DISTATT + float distAtt[3]; /* [MaxDist, RefDist, Rolloff] */ +#endif }; @@ -996,6 +999,77 @@ static ivas_error get_bin_outer_attenuation( return IVAS_ERR_OK; } +#ifdef CONF_DISTATT +/*-----------------------------------------------------------------------------------------* + * 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; +} + +#endif /*-----------------------------------------------------------------------------------------* * Function read_txt_vector() @@ -1128,6 +1202,9 @@ ivas_error RenderConfigReader_checkValues( pRoom_acoustics = &hRenderConfig->roomAcoustics; tab_value_err_count = 0; int16_t wall_idx; +#ifdef CONF_DISTATT + int16_t i; +#endif /* Verify the number of frequency bands in the config input data */ @@ -1245,6 +1322,22 @@ ivas_error RenderConfigReader_checkValues( pRoom_acoustics->AbsCoeff[wall_idx] = ER_MAX_ABS_COEFF; } } + +#ifdef CONF_DISTATT + /* 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] ) ); + } +#endif } @@ -1287,6 +1380,9 @@ ivas_error RenderConfigReader_open( pSelf->pAE = NULL; pSelf->nDP = 0; pSelf->pDP = NULL; +#ifdef CONF_DISTATT + pSelf->distAtt[0] = -1; +#endif *ppRenderConfigReader = pSelf; return IVAS_ERR_OK; @@ -1806,6 +1902,36 @@ static ivas_error RenderConfigReader_readBinary( } } } +#ifdef CONF_DISTATT + /**********************************/ + /* 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; + } + } +#endif + /* Cleanup */ free( pRenderConfigReader->pBitstream ); @@ -2486,18 +2612,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 +2648,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 +2668,34 @@ ivas_error RenderConfigReader_read( { if ( strcmp( pValue, "CREND" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_CREND; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_CREND; } else if ( strcmp( pValue, "FASTCONV" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV; } else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; } else if ( strcmp( pValue, "TDREND" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND; } else { errorHandler( pValue, ERROR_VALUE_INVALID ); } } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#endif #ifdef DEBUGGING else { @@ -2653,6 +2788,54 @@ ivas_error RenderConfigReader_read( free( pValue ); accDPIdx++; } +#ifdef CONF_DISTATT + 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 ); + } +#endif + else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; @@ -2821,6 +3004,12 @@ ivas_error RenderConfigReader_getAcousticEnvironment( pAcEnv->AbsCoeff[j] = pRenderConfigReader->pAE[n].pEarlyReflections->pAbsCoeff[j]; } } +#ifdef FIX_1053_REVERB_RECONFIGURATION + else + { + pAcEnv->use_er = false; + } +#endif return IVAS_ERR_OK; } } @@ -2903,6 +3092,34 @@ ivas_error RenderConfigReader_getDirectivity( return IVAS_ERR_OK; } +#ifdef CONF_DISTATT +/*------------------------------------------------------------------------------------------* + * 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; +} +#endif /*------------------------------------------------------------------------------------------* * RenderConfigReader_close() diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 445ced79abdb905cc094a5b8d51311d4f3f8f4ba..4fb9280ff14c2831bfff92d6bccc579f97e2beff 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -62,6 +62,12 @@ ivas_error RenderConfigReader_getDirectivity( uint16_t *pId, /* i : Directivity pattern ID */ float *directivity /* o : Target directivity */ ); +#ifdef CONF_DISTATT +ivas_error RenderConfigReader_getDistanceAttenuation( + RenderConfigReader *pRenderConfigReader, /* i : RenderConfigReader handle */ + float *distAtt /* o : Distance attenuation */ +); +#endif /* 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..9ca1000770d09fdb4761905604af3cda20cb15fb 100644 --- a/lib_util/split_rend_bfi_file_reader.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -32,10 +32,8 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_rend_bfi_file_reader.h" -#include -#include +#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index d1a85776bd61eaf1aa9cda995c4a312d98aebc1e..6a676235be767e8ca22ce41af3cc77db9b583f54 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -32,15 +32,10 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_render_file_read_write.h" -#include +#ifdef SPLIT_REND_WITH_HEAD_ROT #include -#include -#include -#include "cmdl_tools.h" #include "prot.h" -#include "ivas_cnst.h" /*------------------------------------------------------------------------------------------* @@ -68,7 +63,17 @@ struct SplitFileReadWrite ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, - char *filename ) + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -104,6 +109,40 @@ ivas_error split_rend_reader_open( fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file ); + /* read codec signalling */ + if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read pose correction signalling */ + if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read transport codec frame size signalling */ + if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* read isar bitstream frame size signalling */ + if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read sampling rate signalling */ + if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read LC3plus highres signalling */ + if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#endif + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; return IVAS_ERR_OK; @@ -120,7 +159,17 @@ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, const int16_t delayNumSamples, - const int32_t delayTimeScale ) + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres +#endif +) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -155,6 +204,40 @@ ivas_error split_rend_writer_open( hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale ); fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ); + /* Write codec signalling */ + if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write pose correction signalling */ + if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write transport codec frame size signalling */ + if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Write isar bit stream frame size signalling */ + if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write sampling rate signalling */ + if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write LC3plus highres signalling */ + if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#endif + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; return IVAS_ERR_OK; @@ -167,7 +250,7 @@ ivas_error split_rend_writer_open( * *-----------------------------------------------------------------------------------------*/ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ) { if ( ( *hhSplitRendFileReadWrite ) != NULL ) @@ -182,7 +265,7 @@ ivas_error split_rend_reader_writer_close( *hhSplitRendFileReadWrite = NULL; } - return IVAS_ERR_OK; + return; } @@ -196,10 +279,7 @@ ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ) + int32_t *bits_written ) { char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; size_t header_len, i, num_bytes; @@ -232,23 +312,6 @@ ivas_error split_rend_write_bitstream_to_file( return IVAS_ERR_FAILED_FILE_WRITE; } - /* Write codec signalling */ - if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - - /* Write pose correction signalling */ - if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - /* Write frame size signalling */ - if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - /* write num bytes */ if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -278,10 +341,7 @@ ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC *codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ) + int32_t *bits_written ) { char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; @@ -326,23 +386,6 @@ ivas_error split_rend_read_bits_from_file( return IVAS_ERR_FAILED_FILE_READ; } - /* read codec signalling */ - if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - - /* read pose correction signalling */ - if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - /* read frame size signalling */ - if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - /* write num bytes */ if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -354,7 +397,7 @@ ivas_error split_rend_read_bits_from_file( { return IVAS_ERR_FAILED_FILE_READ; } - for ( i = 0; i < IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) + for ( i = 0; i < ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) { bits[num_bytes + i] = 0; } diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index e933fe3df3a2f5f955a9c62f19c8c773f8efcdf5..ea277cfc52a57caf2e0412561306569441494b02 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -41,7 +41,17 @@ typedef struct SplitFileReadWrite SplitFileReadWrite; /* Allocates and initializes a a split renderer reader instance */ ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, - char *filename ); + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +); /* Allocates and initializes a a split renderer writer instance */ @@ -49,10 +59,21 @@ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, const int16_t delayNumSamples, - const int32_t delayTimeScale ); + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres +#endif +); + /* Closes the split renderer reader/writer and deallocates memory */ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ); /*write split rend coded bitstream to file */ @@ -60,20 +81,14 @@ ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ); + int32_t *bits_written ); /* read split rend coded bits from file */ ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC *codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ); + int32_t *bits_written ); /* read split pre rend delay */ ivas_error split_rend_read_pre_rend_delay_ns( diff --git a/readme.txt b/readme.txt index 25275a79516b91aa8a0d3fa8131155cd441f5e68..e7e5d432f5b79d58fa6f15574326f3b3f03d95fc 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 @@ -239,7 +242,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. @@ -284,6 +288,7 @@ Options: specified) for binaural output configuration -aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. -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 @@ -314,7 +319,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 : Acoustic environment ID (number > 0) or + a sequence thereof in the format [ID1:duration1,ID2:duration2...] + without braces and spaces, with ':' character separating ID from duration and ',' separating + ID and duration pairs, where duration is specified in frames + 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) @@ -325,11 +334,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 e3e1a31114d97be31cace9e45e7bacc718fdabff..caede15c01cab82739000bc773292a60154fa4c8 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/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 @@ -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 @@ -1292,6 +1308,18 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 16 bit testv/stv51MC48c.wav_MC51_512000_48-16_MC_Config_renderer.tst +// Multi-channel 5_1 at 512 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (CREND) +//../IVAS_cod -mc 5_1 512000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:200,0:100,2:500 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_512000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 64 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (FastConv) +//../IVAS_cod -mc 5_1 64000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,2:100,0:300 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_64000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 32 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (ParamBin) +//../IVAS_cod -mc 5_1 32000 48 testv/stv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 0:100,2:500,1:200 BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_32000_48-48_MC_reverb_sequence.tst + // Multi-channel 5_1 at 32 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config hospital_patientroom ../IVAS_cod -mc 5_1 32000 48 testv/stv51MC48c.wav bit ../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/stv51MC48c.wav_MC51_32000_48-48_MC_Config_hospital_patientroom.tst @@ -1336,6 +1364,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 +1410,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 +1552,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 @@ -1729,7 +1779,7 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // 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 +1805,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 91cebec595a4a70d460b786aa69852f963f25a2f..f8888c56c11edc3af003b2072e38b2929c408f49 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 @@ -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 @@ -1291,6 +1307,18 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 ../IVAS_cod -mc 5_1 512000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_renderer.cfg BINAURAL_ROOM_REVERB 16 bit testv/ltv48_MC51.wav_MC51_512000_48-16_MC_Config_renderer.tst +// Multi-channel 5_1 at 512 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (CREND) +//../IVAS_cod -mc 5_1 512000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,0:1000,2:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_512000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 64 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (FastConv) +//../IVAS_cod -mc 5_1 64000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 1:500,2:500,0:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_64000_48-48_MC_reverb_sequence.tst + +// Multi-channel 5_1 at 32 kbps, 48kHz in 48kHz out, BINAURAL_ROOM_REVERB out custom acoustic environment with a sequence (ParamBin) +//../IVAS_cod -mc 5_1 32000 48 testv/ltv51MC48c.wav bit +//../IVAS_dec -render_config testv/rend_config_combined.cfg -aeid 0:1000,2:500,1:500 BINAURAL_ROOM_REVERB 48 bit testv/ltv51MC48c.wav_MC51_32000_48-48_MC_reverb_sequence.tst + // Multi-channel 5_1 at 32 kbps, 48kHz in, 48kHz out, BINAURAL_ROOM_REVERB out Config hospital_patientroom ../IVAS_cod -mc 5_1 32000 48 testv/ltv48_MC51.wav bit ../IVAS_dec -render_config testv/rend_config_hospital_patientroom.cfg BINAURAL_ROOM_REVERB 48 bit testv/ltv48_MC51.wav_MC51_80000_48-48_MC_Config_hospital_patientroom.tst @@ -1377,6 +1405,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 @@ -1728,12 +1775,12 @@ eid-xor -fer -vbr -bs g192 -ep g192 bit ../scripts/dly_error_profiles/ep_5pct.g1 // 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..e57db546badc366bb2d976c8d3fddbf2221bcc24 100644 --- a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c @@ -30,44 +30,53 @@ 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" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "lc3.h" +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT - +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#define MAX_SAMPLES_PER_CHANNEL 960 / 4 +#else #define MAX_SAMPLES_PER_CHANNEL 960 +#endif +#define DEFAULT_BPS 256000 -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 +86,66 @@ 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + 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 ); +#else + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); +#endif 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 +159,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 +193,81 @@ 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif /* 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + uint32_t limitedBitrate; +#endif + ISAR_LC3PLUS_ENC_HANDLE encHandle; + err = ISAR_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* setting an invalid bitrate should result in a limited bitrate*/ + if ( IVAS_ERR_OK != err ) +#else /* setting an invalid bitrate should trigger an error - which is what we expect */ if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) +#endif { return 1; } - err = IVAS_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + limitedBitrate = lc3plus_enc_get_real_bitrate(encHandle->handles[0]); + if(limitedBitrate != 320000) + { + return 1; + } +#endif + 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 +279,16 @@ 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 +299,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 +314,28 @@ 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out, bsSize ) ) +#else + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) +#endif { 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 ) ) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + 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 ) ) +#else + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != ISAR_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) +#endif { return 1; } @@ -261,7 +345,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 +361,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 +381,13 @@ 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, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -310,17 +397,20 @@ 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, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif + ISAR_LC3PLUS_DEC_HANDLE decHandle; + err = ISAR_LC3PLUS_DEC_Open( config, #ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING 1 /*caching enabled*/, #endif @@ -330,7 +420,7 @@ static int openCloseDecoderWithoutCaching( void ) return err; } - IVAS_LC3PLUS_DEC_Close( &decHandle ); + ISAR_LC3PLUS_DEC_Close( &decHandle ); return 0; } @@ -338,11 +428,15 @@ 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 +452,15 @@ 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 +476,19 @@ 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 +496,20 @@ 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out, bitstreamSizePerIvasFrame ); +#else + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); +#endif if ( IVAS_ERR_OK != err ) return err; - IVAS_LC3PLUS_ENC_Close( &encHandle ); + ISAR_LC3PLUS_ENC_Close( &encHandle ); free( bitstream_out ); return 0; } @@ -413,39 +518,46 @@ 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 }; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; +#endif 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out, bitstreamSizePerIvasFrame ); +#else + err = ISAR_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); +#endif 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 +573,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,147 +593,272 @@ 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3plus10ms_48kHz( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; +#endif + 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .isar_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; +#endif + 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 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + 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 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .isar_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, DEFAULT_BPS ); } -#include "ivas_lc3plus_unit_test_selective_decoding.c" +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_80kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 82*1000 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_96kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + 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 +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 126*1000 ); +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 800*1000 ); +} +#endif + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_204800bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 204800 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_205600bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 205600 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_206400bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 206400 ); +} + +static int encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_207200bpsPerChannel( void ) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 1, .samplerate = 48000, .high_res_mode_enabled = 0 }; +#else + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .isar_frame_duration_us = 10 * 1000, .channels = 2, .samplerate = 48000 }; +#endif + return encodeAndDecodeOneStereoFrame( config, config.channels * 207200 ); +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "ivas_lc3plus_unit_test_payload_format.c" +#endif 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; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ret = encodeAndDecodeOneStereoFrameIvas10msLc3_10ms_48kHz_800kbpsPerChannel(); if ( ret != 0 ) - return ret; - ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first(); + return 1; +#endif + /* 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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ret = run_all_payload_tests(); if ( ret != 0 ) - return ret; + return 1; #endif - return ret; + return 0; } #else int main( void ) 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..a303d01f53ee873fe70c0fbad2a9b6a540daa154 --- /dev/null +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_payload_format.c @@ -0,0 +1,451 @@ +/****************************************************************************************************** + +(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" + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + +/* 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; +} +#endif 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..34e92b715a3a42ca9ee66264d3aba68af588201a 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", @@ -165,17 +163,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 +189,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 +335,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 +434,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..6d9398524300be18eb97379aa5e936d783af28ac 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -312,6 +312,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 +348,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 +487,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 +523,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 +547,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..ca71224aea36a0f266b91d4226e1eed3be302fdb 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 @@ -354,8 +372,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 +411,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 +428,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 +520,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 +539,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..9717af0b81fb83eed279793470977f6a3b10c7ec 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,7 @@ def run_renderer( hrtf_file: Optional[str] = None, get_mld=False, mld_lim=0, + get_mld_lim=0, ) -> str: # prepare arguments and filepaths if trj_file is not None: @@ -195,7 +242,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)]) @@ -238,6 +285,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 +296,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 @@