Skip to content
Commits on Source (725)
......@@ -3,17 +3,21 @@
# Compiler output Unix
IVAS_cod
IVAS_dec
IVAS_rend
IVAS_crend_unit_test
obj/
*.a
*.o
*.P
# default CMake
build/**/*
build*/**/*
# Compiler output VS2017
IVAS_cod.exe
IVAS_dec.exe
IVAS_rend.exe
IVAS_crend_unit_test.exe
*.user
.vs/
Debug_*/
......@@ -31,13 +35,10 @@ scripts/ivas_pytests/tests/unit_tests/crend/Release_*/
scripts/td_object_renderer/object_renderer_standalone/renderer_standalone
scripts/td_object_renderer/object_renderer_standalone/renderer_standalone.exe
# Prerenderer
scripts/prerenderer/IVAS_prerenderer
scripts/prerenderer/IVAS_prerenderer.exe
# General/scripts
.DS_Store
.vscode
.cache
*.log
*.bak
scripts/c-code_instrument/
......@@ -46,8 +47,15 @@ scripts/ref/
scripts/test/
scripts/out/
scripts/self_test_summary.txt
tests/renderer/cut
tests/renderer/ref
tests/dut
tests/ref
# Python files that pop up when running scripts
__pycache__/
*.py[cod]
*$py.class
#history
.history/
variables:
TESTV_DIR: "/usr/local/testv"
LTV_DIR: "/usr/local/ltv"
BUILD_OUTPUT: "build_output.txt"
EVS_BE_TEST_DIR: "/usr/local/be_2_evs_test"
SANITIZER_TESTS: "CLANG1 CLANG2"
OUT_FORMATS_CHANNEL_BASED: "stereo mono 5_1 5_1_2 5_1_4 7_1 7_1_4"
OUT_FORMATS_SCENE_BASED: "FOA HOA2 HOA3"
OUT_FORMATS_BINAURAL: "BINAURAL BINAURAL_ROOM"
EXIT_CODE_NON_BE: 123
EXIT_CODE_FAIL: 1
# This sets when pipelines are created. Jobs have more specific rules to restrict them.
......@@ -19,6 +26,7 @@ stages:
- build
- test
- compare
- validate
# ---------------------------------------------------------------
# Generic script anchors
......@@ -37,6 +45,63 @@ stages:
.get-previous-merge-commit-sha: &get-previous-merge-commit-sha
- previous_merge_commit=$(git --no-pager log --merges HEAD~1 -n 1 --pretty=format:%H)
.mr-fetch-target-branch: &mr-fetch-target-branch
# first delete local target branch to avoid conflicts when branch is cached and there are merge conflicts during fetching
# depending on chaching, the branch may not be there, so prevent failure of this command -> should maybe be done smarter later
- git branch -D $CI_MERGE_REQUEST_TARGET_BRANCH_NAME || true
# needed when depth is lower than the number of commits in the branch
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
.mr-get-target-commit: &mr-get-target-commit
# compare to last target branch commit before pipeline was created
- target_commit=$(git log $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -1 --oneline --before=${CI_PIPELINE_CREATED_AT} --format=%H)
.merge-request-comparison-setup-codec:
&merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons
- make clean
- mkdir build
- cd build
- cmake ..
- make -j
- mv IVAS_cod ../IVAS_cod_test
- mv IVAS_dec ../IVAS_dec_test
- mv IVAS_rend ..
- cd ..
- rm -rf build/*
### store the current commit hash
- source_branch_commit_sha=$(git rev-parse HEAD)
### checkout version to compare against
- *mr-fetch-target-branch
- *mr-get-target-commit
- git checkout $target_commit
### build reference binaries
- cd build
- cmake ..
- make -j
- mv IVAS_cod ../IVAS_cod_ref
- mv IVAS_dec ../IVAS_dec_ref
- cd ..
# rename test binaries back
- mv IVAS_cod_test IVAS_cod
- mv IVAS_dec_test IVAS_dec
.merge-request-comparison-check: &merge-request-comparison-check
- if [ $zero_errors != 1 ]; then echo "Run errors encountered!"; exit $EXIT_CODE_FAIL; fi
- if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "Non-bitexact cases without non-BE tag encountered!"; exit $EXIT_CODE_FAIL; fi
- if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; exit $EXIT_CODE_NON_BE; fi
- exit 0
.update-ltv-repo: &update-ltv-repo
- cd $LTV_DIR
- git pull
- cd -
# ---------------------------------------------------------------
# Job templates
......@@ -101,6 +166,25 @@ stages:
- 123
# ---------------------------------------------------------------
# Validation jobs
# ---------------------------------------------------------------
check-if-branch-is-up-to-date-with-main:
extends:
- .rules-merge-request
stage: validate
needs: []
tags:
- ivas-linux
script:
- echo $CI_COMMIT_SHA
- echo $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- commits_behind_count=$(git rev-list --count $CI_COMMIT_SHA..origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME)
- echo $commits_behind_count
- if [ $commits_behind_count -eq 0 ]; then exit 0; else exit 1; fi;
# ---------------------------------------------------------------
# Build jobs
# ---------------------------------------------------------------
......@@ -125,16 +209,6 @@ build-unittests-linux:
# need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...<
- ci/check_for_warnings.py $BUILD_OUTPUT || exit $?
build-prerenderer-linux:
extends:
- .build-job-with-check-for-warnings
- .rules-basis
script:
- *print-common-info
- make -C scripts/prerenderer -j 2>&1 | tee $BUILD_OUTPUT
# need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...<
- ci/check_for_warnings.py $BUILD_OUTPUT || exit $?
build-td-object-renderer-standalone-linux:
extends:
- .build-job-with-check-for-warnings
......@@ -176,7 +250,6 @@ build-codec-sanitizers-linux:
- *print-common-info
- bash ci/build_codec_sanitizers_linux.sh
# ---------------------------------------------------------------
# Test jobs for merge requests
# ---------------------------------------------------------------
......@@ -201,8 +274,7 @@ codec-smoke-test:
- out/logs/
- smoke_test_output.txt
- smoke_test_output_plc.txt
expose_as: 'Smoke test results'
expose_as: "Smoke test results"
# code selftest testvectors with memory-sanitizer binaries
msan-on-merge-request-linux:
......@@ -223,8 +295,7 @@ msan-on-merge-request-linux:
paths:
- scripts/ref/logs/
- test_output.txt
expose_as: 'Msan selftest results'
expose_as: "Msan selftest results"
# code selftest testvectors with address-sanitizer binaries
asan-on-merge-request-linux:
......@@ -245,86 +316,185 @@ asan-on-merge-request-linux:
paths:
- scripts/ref/logs/
- test_output.txt
expose_as: 'Asan selftest results'
expose_as: "Asan selftest results"
# test external renderer executable
external-renderer-make-pytest:
extends:
- .test-job-linux
- .rules-merge-request
needs: ["build-codec-linux-make"]
stage: test
script:
- make -j IVAS_rend
- make -j unittests
- make -j --directory scripts/td_object_renderer/object_renderer_standalone
- python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results"
when: always
paths:
- report-junit.xml
expose_as: "external renderer make pytest results"
reports:
junit:
- report-junit.xml
# compare bit exactness between target and source branch
self-test-on-merge-request:
# test external renderer executable with cmake + asan
external-renderer-cmake-asan-pytest:
extends:
- .test-job-linux
- .rules-merge-request
needs: ["build-codec-linux-cmake"]
stage: test
script:
- python3 ci/disable_ram_counting.py
- cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true
- cmake --build cmake-build -- -j
- python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results"
when: always
paths:
- report-junit.xml
expose_as: "external renderer cmake asan pytest results"
reports:
junit:
- report-junit.xml
# test external renderer executable with cmake + msan
external-renderer-cmake-msan-pytest:
extends:
- .test-job-linux
- .rules-merge-request
needs: ["build-codec-linux-cmake"]
stage: test
script:
- python3 ci/disable_ram_counting.py
- cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true
- cmake --build cmake-build -- -j
- python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results"
when: always
paths:
- report-junit.xml
expose_as: "external renderer cmake msan pytest results"
reports:
junit:
- report-junit.xml
# test external renderer executable with cmake vs decoder renderer
# TODO @tmu @knj @sgi -> converted to script, decide whether to re-enable later
.external-renderer-cmake-vs-decoder-pytest:
extends:
- .test-job-linux
- .rules-merge-request
needs: ["build-codec-linux-cmake"]
stage: test
script:
- cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP=true
- cmake --build cmake-build -- -j
- python3 -m pytest -q --log-level ERROR -n 1 -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_vs_decoder.py
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results"
when: always
paths:
- report-junit.xml
expose_as: "external renderer cmake vs decoder results"
reports:
junit:
- report-junit.xml
# compare external renderer bitexactness between target and source branch
external-renderer-pytest-on-merge-request:
extends:
- .test-job-linux
- .rules-merge-request
needs: ["build-codec-linux-make"]
# TODO: set reasonable timeout, will most likely take less
timeout: "20 minutes"
stage: compare
needs: [ "build-codec-linux-cmake", "codec-smoke-test" ]
timeout: "10 minutes"
script:
- *print-common-info
### build test binaries, initial clean for paranoia reasons
- make clean
- mkdir build
- cd build
- cmake ..
- make -j
- mv IVAS_cod ../IVAS_cod_test
- mv IVAS_dec ../IVAS_dec_test
- cd ..
- rm -rf build/*
### store the current commit hash
- source_branch_commit_sha=$(git rev-parse HEAD)
# some helper variables - "|| true" to prevent failures from grep not finding anything
- non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend(erer)*[ -]*non[ -]*be\]") || true
# TODO: needs splitting the test between reference and cut generation
#- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true
### checkout version to compare against
# first delete local target branch to avoid conflicts when branch is cached and there are merge conflicts during fetching
# depending on chaching, the branch may not be there, so prevent failure of this command -> should maybe be done smarter later
- git branch -D $CI_MERGE_REQUEST_TARGET_BRANCH_NAME || true
# needed when depth is lower than the number of commits in the branch
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
# store the current commit hash
- source_branch_commit_sha=$(git rev-parse HEAD)
### compare to last target branch commit before pipeline was created
- target_commit=$(git log $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -1 --oneline --before=${CI_PIPELINE_CREATED_AT} --format=%H)
- *mr-fetch-target-branch
- *mr-get-target-commit
- git checkout $target_commit
### build reference binaries
- cd build
- cmake ..
- make -j
- mv IVAS_cod ../IVAS_cod_ref
- mv IVAS_dec ../IVAS_dec_ref
- cd ..
# build reference binaries
- make -j IVAS_rend
- mv IVAS_rend IVAS_rend_ref
### re-checkout the commit from the source branch to have up-to-date self_test.py and scripts/testv (and actually everything)
# back to source branch
- git checkout $source_branch_commit_sha
- make clean
- make -j IVAS_rend
### run selftest
- ls -altr scripts/testv
- python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt
# run test
- exit_code=0
- python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_be_comparison.py || exit_code=$?
- zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true
- *merge-request-comparison-check
### analyse test output
allow_failure:
exit_codes:
- 123
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results"
when: always
paths:
- report-junit.xml
expose_as: "pytest external renderer results"
reports:
junit:
- report-junit.xml
# compare bit exactness between target and source branch
ivas-pytest-on-merge-request:
extends:
- .test-job-linux
- .rules-merge-request
stage: compare
needs: ["build-codec-linux-cmake", "codec-smoke-test"]
timeout: "10 minutes"
script:
- *print-common-info
- *merge-request-comparison-setup-codec
# some helper variables - "|| true" to prevent failures from grep not finding anything
- non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true
- run_errors=$(cat test_output.txt | grep -c "test conditions had run errors") || true
- bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true
- EXIT_CODE_NON_BE=123
- EXIT_CODE_FAIL=1
- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true
- selftest_exit_code=0
### If ref_using_main is not set, checkoug the source branch to use scripts and input from there
- if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi
# check for crashes during the test, if any happened, fail the test
- if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi
### prepare pytest
# create short test vectors
- python3 tests/create_short_testvectors.py
# create references
- python3 -m pytest tests -v --update_ref 1 -m create_ref
- python3 -m pytest tests -v --update_ref 1 -m create_ref_part2
# check for non bitexact output and store exit code to also always run the SBA pytest
- if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi
- if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi
### Run test using branch scripts and input
- if [ $ref_using_main == 1 ]; then git checkout $source_branch_commit_sha; fi
### run SBA pytest
### run pytest
- exit_code=0
- python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$?
- if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi
- python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$?
- zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true
- if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi
- if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi;
# return exit code from selftest if everything went well with the pytest run
- exit $selftest_exit_code
- *merge-request-comparison-check
allow_failure:
exit_codes:
- 123
......@@ -332,14 +502,100 @@ self-test-on-merge-request:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results"
when: always
paths:
- test_output.txt
- scripts/test/logs/
- scripts/ref/logs/
- report-junit.xml
expose_as: 'Self test results'
expose_as: "pytest ivas results"
reports:
junit: report-junit.xml
junit:
- report-junit.xml
evs-pytest-on-merge-request:
extends:
- .test-job-linux
- .rules-merge-request
stage: compare
needs: ["build-codec-linux-cmake", "codec-smoke-test"]
timeout: "10 minutes"
script:
- *print-common-info
- *merge-request-comparison-setup-codec
# some helper variables - "|| true" to prevent failures from grep not finding anything
- non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[evs[ -]*non[ -]*be\]") || true
- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true
### If ref_using_main is not set, checkoug the source branch to use scripts and input from there
- if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi
### prepare pytest
# create references
- python3 -m pytest tests/test_param_file.py -v --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm
### Run test using branch scripts and input
- if [ $ref_using_main == 1 ]; then git checkout $source_branch_commit_sha; fi
### run pytest for EVS cases
- exit_code=0
- python3 -m pytest tests/test_param_file.py -v --param_file scripts/config/self_test_evs.prm --junit-xml=report-junit-evs.xml || exit_code=$?
- zero_errors=$(cat report-junit-evs.xml | grep -c 'errors="0"') || true
- *merge-request-comparison-check
allow_failure:
exit_codes:
- 123
artifacts:
name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results"
when: always
paths:
- report-junit-evs.xml
expose_as: "pytest evs results"
reports:
junit:
- report-junit-evs.xml
clang-format-check:
extends:
- .test-job-linux
- .rules-merge-request
variables:
ARTIFACT_BASE_NAME: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--formatting-fix"
stage: validate
needs: []
timeout: "5 minutes"
script:
# Set up variables. This can't be done in the "variables" section because variables are not expanded properly there
- PATCH_FILE_NAME="$ARTIFACT_BASE_NAME".patch
- >
INSTRUCTIONS_GITLAB="To fix formatting issues:\n
- download the diff patch available as artifact of this job\n
- unzip the artifact and place the patch file in the root directory of your local IVAS repo\n
- run: git apply $PATCH_FILE_NAME\n
- commit new changes"
- >
INSTRUCTIONS_README="To fix formatting issues:\n
- place the patch file in the root directory of your local IVAS repo\n
- run: git apply $PATCH_FILE_NAME\n
- commit new changes"
- scripts/check-format.sh -af -p 8 || format_problems=$?
- if [ $format_problems == 0 ] ; then exit 0; fi
- mkdir tmp-formatting-fix
- git diff > "tmp-formatting-fix/$PATCH_FILE_NAME"
# Print instructions to job output
- echo -e "$INSTRUCTIONS_GITLAB"
# Include readme in the artifact, in case someone misses the job printout (e.g. getting the artifact via MR interface)
- echo -e "$INSTRUCTIONS_README" > "tmp-formatting-fix/readme.txt"
- exit $format_problems
artifacts:
paths:
- tmp-formatting-fix/
when: on_failure
name: "$ARTIFACT_BASE_NAME"
expose_as: 'formatting patch'
# ---------------------------------------------------------------
# Test jobs for main branch
......@@ -372,7 +628,6 @@ be-2-evs-linux:
- cd evs_be_test
- python3 ../ci/run_evs_be_test.py
codec-comparison-on-main-push:
extends:
- .test-job-linux
......@@ -412,40 +667,33 @@ codec-comparison-on-main-push:
- mv IVAS_dec ../IVAS_dec_ref
- cd ..
### re-checkout the latest commit in the main branch
- git checkout $latest_commit
### run selftest
- ls -altr scripts/testv
- python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt
### analyse test output
# some helper variables - "|| true" to prevent failures from grep not finding anything
- non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true
- run_errors=$(cat test_output.txt | grep -c "test conditions had run errors") || true
- bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true
- EXIT_CODE_NON_BE=123
- EXIT_CODE_FAIL=1
# helper variable - "|| true" to prevent failures from grep not finding anything
- non_be_flag=$(echo $CI_COMMIT_MESSAGE | grep -c --ignore-case "\[non[ -]*be\]") || true
- ref_using_main=$(echo $CI_COMMIT_MESSAGE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true
- selftest_exit_code=0
### re-checkout the latest commit in the main branch, if ref_using_main is not set
- if [ $ref_using_main == 0 ]; then git checkout $latest_commit;fi
# check for crashes during the test, if any happened, fail the test
- if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi
### prepare pytest
# create short test vectors
- python3 tests/create_short_testvectors.py
# rename test binaries back
- mv IVAS_cod_test IVAS_cod
- mv IVAS_dec_test IVAS_dec
# create references
- python3 -m pytest tests -v --update_ref 1 -m create_ref
- python3 -m pytest tests -v --update_ref 1 -m create_ref_part2
# check for non bitexact output and store exit code to also always run the SBA pytest
- if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi
- if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi
### re-checkout the latest commit here, if ref_using_main is set
- if [ $ref_using_main -eq 1 ]; then git checkout $latest_commit;fi
### run SBA pytest
### run pytest
- exit_code=0
- python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$?
- python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$?
- if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi
- zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true
- if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi
- if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi;
# return exit code from selftest if everything went well with the pytest run
- exit $selftest_exit_code
allow_failure:
exit_codes:
- 123
......@@ -453,42 +701,195 @@ codec-comparison-on-main-push:
name: "main-push--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results"
when: always
paths:
- test_output.txt
- scripts/test/logs/
- scripts/ref/logs/
- report-junit.xml
expose_as: 'Results of comparison to previous merge commit'
expose_as: "Results of comparison to previous merge commit"
reports:
junit: report-junit.xml
# parameterizable job for sanitizer tests per format
# how to set up: create a schedule (CI/CD -> schedules) and enter the respective values for the environment variables:
# - SANITIZER_TEST_IN_FMT: input format
# - SANITIZER_TEST_OUT_FMTS: list of output formats, blank-separated, e.g.: stereo mono 5_1
# - SANITIZER_TEST_TESTS: list of checks to do, can be one of CLANG1, CLANG2, CLANG3, VALGRIND
sanitizer-test-on-main-scheduled:
# ---------------------------------------------------------------
# Scheduled jobs on main
# ---------------------------------------------------------------
.sanitizer-test-template:
extends:
# TODO: still needed since MASA ltv vectors are not there yet
# when they were added, we can add a needs-ltv-dir template
- .test-job-linux-needs-testv-dir
# this next one is maybe not really needed, since there is the rule checking for the existence of the env vars below, but use for clarity
- .rules-main-scheduled
stage: test
tags:
- sanitizer_test_main
stage: test
rules:
# only run in scheduled pipeline that passes this env vars
- if: $SANITIZER_TEST_IN_FMT && $SANITIZER_TEST_OUT_FMTS && $SANITIZER_TEST_TESTS
script:
- *print-common-info
- echo "Running scheduled sanitizer tests $SANITIZER_TEST_TESTS for input format $SANITIZER_TEST_IN_FMT and output format(s) $SANITIZER_TEST_OUT_FMTS"
- python3 ci/run_scheduled_sanitizer_test.py $SANITIZER_TEST_IN_FMT $SANITIZER_TEST_OUT_FMTS --tests $SANITIZER_TEST_TESTS
artifacts:
name: "sanitizer-test-results-and-error_pattern-$SANITIZER_TEST_IN_FMT-in-$SANITIZER_TEST_OUT_FMTS-out"
name: "$CI_JOB_NAME--main--sha-$CI_COMMIT_SHORT_SHA"
when: always
paths:
- ep_015.g192
- "./*/logs"
# second wildcard is necessary to get encoder and no-PLC run logs
- "CLANG*/logs*"
### --- sanitizer schedule A ---
.sanitizer-test-schedule-A:
extends:
- .sanitizer-test-template
timeout: 2 hours 30 minutes
sanitizer-test-mono:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
script:
- *update-ltv-repo
- python3 ci/run_scheduled_sanitizer_test.py mono mono --tests $SANITIZER_TESTS
sanitizer-test-stereo:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 2 hours 30 minutes
script:
- *update-ltv-repo
- python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED --tests $SANITIZER_TESTS
sanitizer-test-stereodmxevs:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 5 hours
script:
- *update-ltv-repo
- python3 ci/run_scheduled_sanitizer_test.py StereoDmxEVS mono --tests $SANITIZER_TESTS
sanitizer-test-ism1:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 7 hours 30 minutes
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
sanitizer-test-ism2:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 10 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
sanitizer-test-ism3:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 12 hours 30 minutes
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
sanitizer-test-ism4:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 15 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
sanitizer-test-masa:
extends: .sanitizer-test-schedule-A
rules:
- if: $SANITIZER_SCHEDULE_A
when: delayed
start_in: 17 hours 30 minutes
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
### --- sanitizer schedule B ---
.sanitizer-test-schedule-B:
extends:
- .sanitizer-test-template
timeout: 3 hours
sanitizer-test-mc-5_1:
extends: .sanitizer-test-schedule-B
rules:
- if: $SANITIZER_SCHEDULE_B
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
sanitizer-test-mc-5_1_2:
extends: .sanitizer-test-schedule-B
rules:
- if: $SANITIZER_SCHEDULE_B
when: delayed
start_in: 3 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
sanitizer-test-mc-5_1_4:
extends: .sanitizer-test-schedule-B
rules:
- if: $SANITIZER_SCHEDULE_B
when: delayed
start_in: 6 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
sanitizer-test-mc-7_1:
extends: .sanitizer-test-schedule-B
rules:
- if: $SANITIZER_SCHEDULE_B
when: delayed
start_in: 9 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
sanitizer-test-mc-7_1_4:
extends: .sanitizer-test-schedule-B
rules:
- if: $SANITIZER_SCHEDULE_B
when: delayed
start_in: 12 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
### --- sanitizer schedule C ---
.sanitizer-test-schedule-C:
extends:
- .sanitizer-test-template
timeout: 6 hours
sanitizer-test-sba:
extends: .sanitizer-test-schedule-C
rules:
- if: $SANITIZER_SCHEDULE_C
script:
- *update-ltv-repo
- python3 ci/run_scheduled_sanitizer_test.py SBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS
sanitizer-test-planarsba:
extends: .sanitizer-test-schedule-C
rules:
- if: $SANITIZER_SCHEDULE_C
when: delayed
start_in: 6 hours
script:
- *update-ltv-repo
- python3 ci/run_scheduled_sanitizer_test.py PlanarSBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS
# GCOV/LCOV coverage analysis of self_test suite
coverage-test-on-main-scheduled:
......@@ -504,9 +905,10 @@ coverage-test-on-main-scheduled:
script:
- *print-common-info
- make GCOV=1 -j
- ./scripts/self_test.py --create -t 1
- ./scripts/self_test.py --create -t 1 scripts/config/self_test_evs.prm
- ./scripts/ivas_pytests/self_test_b.py --create_only --numprocesses 1 --encref IVAS_cod --decref IVAS_dec --encdut IVAS_cod --decdut IVAS_dec
- python3 tests/create_short_testvectors.py
- python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec
- python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref_part2 --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec
- python3 -m pytest tests/test_param_file.py -v -n 0 --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec
- lcov -c -d obj -o coverage.info
- genhtml coverage.info -o coverage
artifacts:
......@@ -539,4 +941,3 @@ pull-from-3gpp-forge:
# Push to mirror, include tags. Option `-o ci.skip` tells GitLab to skip CI for the pushed commits (assumed already tested upstream)
- git push --tags -o ci.skip "https://${GITLAB_USER_LOGIN}:${MIRROR_ACCESS_TOKEN}@${CI_REPOSITORY_URL#*@}" "HEAD:${CI_COMMIT_BRANCH}"
......@@ -108,6 +108,9 @@ if(WMOPS)
add_definitions("-DWMOPS=1")
endif()
if(DEC_TO_REND_FLOAT_DUMP)
add_compile_definitions(DEC_TO_REND_FLOAT_DUMP)
endif()
project(stereo-evs)
set_property(GLOBAL PROPERTY USE_FOLDERS ON) # make Visual Studio projects look nicer
......@@ -118,6 +121,7 @@ include_directories(
lib_debug
lib_dec
lib_enc
lib_rend
lib_util
)
......@@ -131,21 +135,35 @@ endif()
file(GLOB libDebugSrcs "lib_debug/*.c")
file(GLOB libDebugHeaders "lib_debug/*.h")
add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders})
target_link_libraries(lib_debug lib_com)
file(GLOB libEncSrcs "lib_enc/*.c")
file(GLOB libEncHeaders "lib_enc/*.h")
add_library(lib_enc ${libEncSrcs} ${libEncHeaders})
target_link_libraries(lib_enc lib_com lib_debug)
file(GLOB libRendSrcs "lib_rend/*.c")
file(GLOB libRendHeaders "lib_rend/*.h")
add_library(lib_rend ${libRendSrcs} ${libRendHeaders})
target_link_libraries(lib_rend lib_com lib_debug)
file(GLOB libDecSrcs "lib_dec/*.c")
file(GLOB libDecHeaders "lib_dec/*.h")
add_library(lib_dec ${libDecSrcs} ${libDecHeaders})
target_link_libraries(lib_dec lib_com lib_debug)
target_link_libraries(lib_dec lib_com lib_rend lib_debug)
file(GLOB libUtilSrcs "lib_util/*.c")
file(GLOB libUtilHeaders "lib_util/*.h")
add_library(lib_util ${libUtilSrcs} ${libUtilHeaders})
file(GLOB unitTestCRendSrcs "scripts/ivas_pytests/tests/unit_tests/crend/*.c")
file(GLOB unitTestCRendHeaders "scripts/ivas_pytests/tests/unit_tests/crend/*.h")
add_executable(IVAS_crend_unit_test ${unitTestCRendSrcs} ${unitTestCRendHeaders})
target_link_libraries(IVAS_crend_unit_test lib_rend lib_dec lib_util lib_com lib_debug)
add_executable(renderer_standalone "scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c")
target_link_libraries(renderer_standalone lib_rend lib_dec lib_util lib_com lib_debug)
add_executable(IVAS_cod apps/encoder.c)
target_link_libraries(IVAS_cod lib_enc lib_util)
if(WIN32)
......@@ -158,11 +176,14 @@ if(WIN32)
target_link_libraries(IVAS_dec Ws2_32)
endif()
if(${IVAS_BUILD_PRERENDERER})
add_executable(IVAS_prerenderer
scripts/prerenderer/prerenderer.c
${libEncSrcs}
${libDecSrcs}
)
target_link_libraries(IVAS_prerenderer lib_com lib_dec lib_debug lib_util)
add_executable(IVAS_rend apps/renderer.c)
target_link_libraries(IVAS_rend lib_rend lib_util)
if(COPY_EXECUTABLES_FROM_BUILD_DIR)
# Optionally copy executables to 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 "$<TARGET_FILE:IVAS_cod>" "${CMAKE_CURRENT_SOURCE_DIR}/")
add_custom_command(TARGET IVAS_dec POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:IVAS_dec>" "${CMAKE_CURRENT_SOURCE_DIR}/")
add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:IVAS_rend>" "${CMAKE_CURRENT_SOURCE_DIR}/")
add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:IVAS_crend_unit_test>" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/ivas_pytests/tests/unit_tests/crend/")
add_custom_command(TARGET renderer_standalone POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$<TARGET_FILE:renderer_standalone>" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/td_object_renderer/object_renderer_standalone/")
endif()
......@@ -5,6 +5,7 @@ SRC_LIBCOM = lib_com
SRC_LIBDEBUG = lib_debug
SRC_LIBDEC = lib_dec
SRC_LIBENC = lib_enc
SRC_LIBREND = lib_rend
SRC_LIBUTIL = lib_util
SRC_APP = apps
BUILD = build
......@@ -19,15 +20,17 @@ UTESTS_CREND_DIR = $(UTESTS_DIR)/crend
SRC_UTESTS = $(UTESTS_CREND_DIR)
SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBUTIL) $(SRC_APP) $(SRC_UTESTS))
SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBUTIL) $(SRC_APP) $(SRC_UTESTS))
# Name of CLI binaries
CLI_APIDEC ?= IVAS_dec
CLI_APIENC ?= IVAS_cod
CLI_APIREND ?= IVAS_rend
LIB_LIBCOM ?= libivascom.a
LIB_LIBDEBUG ?= libivasdebug.a
LIB_LIBDEC ?= libivasdec.a
LIB_LIBENC ?= libivasenc.a
LIB_LIBREND ?= libivasrend.a
LIB_LIBUTIL ?= libivasutil.a
CLI_UTESTS_CREND ?= IVAS_crend_unit_test
......@@ -125,6 +128,7 @@ SRCS_LIBCOM = $(foreach DIR,$(SRC_LIBCOM),$(patsubst $(DIR)/%,%,$(wildcard $(D
SRCS_LIBDEBUG = $(foreach DIR,$(SRC_LIBDEBUG),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c)))
SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c)))
SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c)))
SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c)))
SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c)))
SRCS_UTESTS_CREND = $(foreach DIR,$(UTESTS_CREND_DIR),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c)))
......@@ -133,9 +137,11 @@ OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o))
OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o))
OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o))
OBJS_LIBENC = $(addprefix $(OBJDIR)/,$(SRCS_LIBENC:.c=.o))
OBJS_LIBREND = $(addprefix $(OBJDIR)/,$(SRCS_LIBREND:.c=.o))
OBJS_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o))
OBJS_CLI_APIDEC = $(OBJDIR)/decoder.o
OBJS_CLI_APIENC = $(OBJDIR)/encoder.o
OBJS_CLI_APPREND = $(OBJDIR)/renderer.o
OBJS_CLI_UTESTS_CREND = $(addprefix $(OBJDIR)/,$(SRCS_UTESTS_CREND:.c=.o))
......@@ -149,7 +155,7 @@ DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS
.PHONY: all clean clean_unittests clean_all
all: $(CLI_APIENC) $(CLI_APIDEC)
all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND)
$(OBJDIR):
$(QUIET)mkdir -p $(OBJDIR)
......@@ -157,7 +163,7 @@ $(OBJDIR):
$(LIB_LIBCOM): $(OBJS_LIBCOM)
$(QUIET_AR)$(AR) rcs $@ $^
$(LIB_LIBDEC): $(OBJS_LIBDEC)
$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND)
$(QUIET_AR)$(AR) rcs $@ $^
$(LIB_LIBDEBUG): $(OBJS_LIBDEBUG)
......@@ -166,27 +172,33 @@ $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG)
$(LIB_LIBENC): $(OBJS_LIBENC)
$(QUIET_AR)$(AR) rcs $@ $^
$(LIB_LIBREND): $(OBJS_LIBREND)
$(QUIET_AR)$(AR) rcs $@ $^
$(LIB_LIBUTIL): $(OBJS_LIBUTIL)
$(QUIET_AR)$(AR) rcs $@ $^
$(CLI_APIENC): $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(OBJS_CLI_APIENC)
$(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasutil -livasenc -livascom -livasdebug $(LDLIBS) -o $(CLI_APIENC)
$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG)
$(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasenc -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIENC)
$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG)
$(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC)
$(CLI_APIDEC): $(LIB_LIBDEC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(OBJS_CLI_APIDEC)
$(QUIET_LINK)$(CC) $(OBJS_CLI_APIDEC) $(LDFLAGS) -L. -livasutil -livasdec -livascom -livasdebug $(LDLIBS) -o $(CLI_APIDEC)
$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG)
$(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND)
$(CLI_UTESTS_CREND): $(LIB_LIBDEC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBENC) $(LIB_LIBUTIL) $(OBJS_CLI_UTESTS_CREND)
$(QUIET_LINK)$(CC) $(OBJS_CLI_UTESTS_CREND) $(LDFLAGS) -L. -livasutil -livasdec -livascom -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND)
$(CLI_UTESTS_CREND): $(OBJS_CLI_UTESTS_CREND) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG)
$(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_UTESTS_CREND) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND)
unittests: $(CLI_UTESTS_CREND)
libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL)
libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBUTIL)
clean: clean_unittests
$(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(DEPS)
$(QUIET)$(RM) $(DEPS:.P=.d)
$(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR)
$(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_PRD) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL)
$(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND)
clean_unittests:
$(QUIET)$(RM) $(OBJS_UTESTS)
......
......@@ -8,6 +8,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_enc", "lib_enc.vcxproj"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}"
......@@ -16,6 +18,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decoder", "decoder.vcxproj"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj", "{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}"
ProjectSection(SolutionItems) = preProject
..\.clang-format = ..\.clang-format
......@@ -60,6 +64,15 @@ Global
{39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|Win32.ActiveCfg = Unittests|Win32
{39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|Win32.Build.0 = Unittests|Win32
{39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|x64.ActiveCfg = Unittests|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.ActiveCfg = Debug|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.Build.0 = Debug|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|x64.ActiveCfg = Debug|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.ActiveCfg = Release|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|x64.ActiveCfg = Release|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.ActiveCfg = Unittests|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.Build.0 = Unittests|Win32
{718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|x64.ActiveCfg = Release|Win32
{2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.ActiveCfg = Debug|Win32
{2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.Build.0 = Debug|Win32
{2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|x64.ActiveCfg = Debug|Win32
......@@ -96,6 +109,15 @@ Global
{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Unittests|Win32.ActiveCfg = Unittests|Win32
{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Unittests|Win32.Build.0 = Unittests|Win32
{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Unittests|x64.ActiveCfg = Unittests|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.ActiveCfg = Debug|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.Build.0 = Debug|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|x64.ActiveCfg = Debug|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.ActiveCfg = Release|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = Release|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|x64.ActiveCfg = Release|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|Win32.ActiveCfg = Unittests|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|Win32.Build.0 = Unittests|Win32
{12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|x64.ActiveCfg = Release|Win32
{32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|Win32.ActiveCfg = Debug|Win32
{32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|x64.ActiveCfg = Debug|Win32
{32354377-ACA7-40F9-9A0E-87FC956F0B78}.Release|Win32.ActiveCfg = Release|Win32
......
......@@ -78,7 +78,7 @@
</CustomBuildStep>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling />
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
......@@ -109,7 +109,7 @@
</CustomBuildStep>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
......@@ -147,7 +147,7 @@
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
......
......@@ -73,7 +73,7 @@
</CustomBuildStep>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling />
......@@ -97,7 +97,7 @@
</CustomBuildStep>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>
......@@ -124,7 +124,7 @@
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>false</IntrinsicFunctions>
<WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
......
......@@ -89,7 +89,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling />
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
......@@ -126,7 +126,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
......@@ -169,7 +169,7 @@
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
......@@ -264,12 +264,9 @@
<ClCompile Include="..\lib_dec\init_dec.c" />
<ClCompile Include="..\lib_dec\inov_dec.c" />
<ClCompile Include="..\lib_dec\ivas_agc_dec.c" />
<ClCompile Include="..\lib_dec\ivas_allrad_dec.c" />
<ClCompile Include="..\lib_dec\ivas_binauralRenderer.c" />
<ClCompile Include="..\lib_dec\ivas_binaural_reverb.c" />
<ClCompile Include="..\lib_dec\ivas_corecoder_dec_reconfig.c" />
<ClCompile Include="..\lib_dec\ivas_core_dec.c" />
<ClCompile Include="..\lib_dec\ivas_cpe_dec.c" />
<ClCompile Include="..\lib_dec\ivas_crend.c" />
<ClCompile Include="..\lib_dec\ivas_dec.c" />
<ClCompile Include="..\lib_dec\ivas_decision_matrix_dec.c" />
<ClCompile Include="..\lib_dec\ivas_dirac_dec.c" />
......@@ -278,17 +275,13 @@
<ClCompile Include="..\lib_dec\ivas_dirac_onsets_dec.c" />
<ClCompile Include="..\lib_dec\ivas_dirac_output_synthesis_cov.c" />
<ClCompile Include="..\lib_dec\ivas_dirac_output_synthesis_dec.c" />
<ClCompile Include="..\lib_dec\ivas_efap.c" />
<ClCompile Include="..\lib_dec\ivas_entropy_decoder.c" />
<ClCompile Include="..\lib_dec\ivas_hrtf.c" />
<ClCompile Include="..\lib_dec\ivas_init_dec.c" />
<ClCompile Include="..\lib_dec\ivas_ism_metadata_dec.c" />
<ClCompile Include="..\lib_dec\ivas_ism_param_dec.c" />
<ClCompile Include="..\lib_dec\ivas_ism_renderer.c" />
<ClCompile Include="..\lib_dec\ivas_lfe_dec.c" />
<ClCompile Include="..\lib_dec\ivas_lfe_plc.c" />
<ClCompile Include="..\lib_dec\ivas_limiter.c" />
<ClCompile Include="..\lib_dec\ivas_ls_custom_dec.c" />
<ClCompile Include="..\lib_dec\ivas_masa_dec.c" />
<ClCompile Include="..\lib_dec\ivas_mct_core_dec.c" />
<ClCompile Include="..\lib_dec\ivas_mct_dec.c" />
......@@ -296,35 +289,15 @@
<ClCompile Include="..\lib_dec\ivas_mc_param_dec.c" />
<ClCompile Include="..\lib_dec\ivas_mdct_core_dec.c" />
<ClCompile Include="..\lib_dec\ivas_mono_dmx_renderer.c" />
<ClCompile Include="..\lib_dec\ivas_objectRenderer.c" />
<ClCompile Include="..\lib_dec\ivas_objectRenderer_hrFilt.c" />
<ClCompile Include="..\lib_dec\ivas_objectRenderer_mix.c" />
<ClCompile Include="..\lib_dec\ivas_objectRenderer_sfx.c" />
<ClCompile Include="..\lib_dec\ivas_objectRenderer_sources.c" />
<ClCompile Include="..\lib_dec\ivas_objectRenderer_vec.c" />
<ClCompile Include="..\lib_dec\ivas_orient_trk.c" />
<ClCompile Include="..\lib_dec\ivas_output_init.c" />
<ClCompile Include="..\lib_dec\ivas_out_setup_conversion.c" />
<ClCompile Include="..\lib_dec\ivas_pca_dec.c" />
<ClCompile Include="..\lib_dec\ivas_post_proc.c" />
<ClCompile Include="..\lib_dec\ivas_range_uni_dec.c" />
<ClCompile Include="..\lib_dec\ivas_render_config.c" />
<ClCompile Include="..\lib_dec\ivas_reverb.c" />
<ClCompile Include="..\lib_dec\ivas_reverb_delay_line.c" />
<ClCompile Include="..\lib_dec\ivas_reverb_fft_filter.c" />
<ClCompile Include="..\lib_dec\ivas_reverb_filter_design.c" />
<ClCompile Include="..\lib_dec\ivas_reverb_iir_filter.c" />
<ClCompile Include="..\lib_dec\ivas_reverb_utils.c" />
<ClCompile Include="..\lib_dec\ivas_rom_binauralRenderer.c" />
<ClCompile Include="..\lib_dec\ivas_qmetadata_dec.c" />
<ClCompile Include="..\lib_dec\ivas_qspherical_dec.c" />
<ClCompile Include="..\lib_dec\ivas_rom_binaural_crend_head.c" />
<ClCompile Include="..\lib_dec\ivas_rom_dec.c" />
<ClCompile Include="..\lib_dec\ivas_rom_TdBinauralRenderer.c" />
<ClCompile Include="..\lib_dec\ivas_rotation.c" />
<ClCompile Include="..\lib_dec\ivas_sba_dec.c" />
<ClCompile Include="..\lib_dec\ivas_sba_dirac_stereo_dec.c" />
<ClCompile Include="..\lib_dec\ivas_sba_rendering.c" />
<ClCompile Include="..\lib_dec\ivas_sce_dec.c" />
<ClCompile Include="..\lib_dec\ivas_spar_decoder.c" />
<ClCompile Include="..\lib_dec\ivas_spar_md_dec.c" />
......@@ -392,10 +365,7 @@
<ClCompile Include="..\lib_dec\ivas_sns_dec.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\lib_dec\ivas_rom_binauralRenderer.h" />
<ClInclude Include="..\lib_dec\ivas_rom_binaural_crend_head.h" />
<ClInclude Include="..\lib_dec\ivas_rom_dec.h" />
<ClInclude Include="..\lib_dec\ivas_rom_TdBinauralRenderer.h" />
<ClInclude Include="..\lib_dec\ivas_stat_dec.h" />
<ClInclude Include="..\lib_dec\jbm_jb4sb.h" />
<ClInclude Include="..\lib_dec\jbm_jb4_circularbuffer.h" />
......@@ -418,6 +388,10 @@
<Project>{54509728-928b-44d9-a118-a6f92f08b34f}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="lib_rend.vcxproj">
<Project>{718DE063-A18B-BB72-9150-62B892E6FFA6}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -28,24 +28,6 @@
<ClCompile Include="..\lib_dec\ivas_dirac_output_synthesis_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_objectRenderer.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_objectRenderer_hrfilt.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_objectRenderer_mix.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_objectRenderer_sfx.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_objectRenderer_sources.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_objectRenderer_vec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_rom_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
......@@ -406,24 +388,9 @@
<ClCompile Include="..\lib_dec\ivas_ism_renderer.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_limiter.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_output_init.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_init_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_binaural_reverb.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_binauralRenderer.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_rom_binauralRenderer.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_qmetadata_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
......@@ -448,15 +415,9 @@
<ClCompile Include="..\lib_dec\ivas_svd_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_rotation.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_sba_dirac_stereo_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_efap.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_ism_param_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
......@@ -512,42 +473,21 @@
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\lib_dec.c" />
<ClCompile Include="..\lib_dec\ivas_rom_TdBinauralRenderer.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_allrad_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_ls_custom_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_agc_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_crend.c">
<ClCompile Include="..\lib_dec\ivas_spar_foa_md_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_td_decorr.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_reverb_filter_design.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_reverb_iir_filter.c">
<ClCompile Include="..\lib_dec\ivas_spar_foa_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_pca_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_reverb.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_reverb_delay_line.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_reverb_fft_filter.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_lfe_plc.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
......@@ -560,25 +500,10 @@
<ClCompile Include="..\lib_dec\ivas_spar_decoder.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_rom_binaural_crend_head.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_hrtf.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_orient_trk.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_reverb_utils.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_render_config.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_sba_rendering.c">
<ClCompile Include="..\lib_dec\ivas_spar_md_dec.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_dec\ivas_spar_md_dec.c">
<ClCompile Include="..\lib_dec\ivas_corecoder_dec_reconfig.c">
<Filter>dec_ivas_c</Filter>
</ClCompile>
</ItemGroup>
......@@ -595,9 +520,6 @@
<ClInclude Include="..\lib_dec\ivas_rom_dec.h">
<Filter>dec_h</Filter>
</ClInclude>
<ClInclude Include="..\lib_dec\ivas_rom_binauralRenderer.h">
<Filter>dec_h</Filter>
</ClInclude>
<ClInclude Include="..\lib_dec\jbm_jb4_jmf.h">
<Filter>dec_h</Filter>
</ClInclude>
......@@ -623,12 +545,6 @@
<Filter>dec_h</Filter>
</ClInclude>
<ClInclude Include="..\lib_dec\lib_dec.h" />
<ClInclude Include="..\lib_dec\ivas_rom_TdBinauralRenderer.h">
<Filter>dec_h</Filter>
</ClInclude>
<ClInclude Include="..\lib_dec\ivas_rom_binaural_crend_head.h">
<Filter>dec_h</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="dec_all_c">
......
......@@ -89,7 +89,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling />
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
......@@ -129,7 +129,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
......@@ -176,7 +176,7 @@
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
......@@ -206,6 +206,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\lib_enc\ivas_agc_enc.c" />
<ClCompile Include="..\lib_enc\ivas_corecoder_enc_reconfig.c" />
<ClCompile Include="..\lib_enc\ivas_core_pre_proc.c" />
<ClCompile Include="..\lib_enc\ivas_core_pre_proc_front.c" />
<ClCompile Include="..\lib_enc\ivas_enc_cov_handler.c" />
......
......@@ -581,6 +581,9 @@
<ClCompile Include="..\lib_enc\ivas_spar_md_enc.c">
<Filter>enc_ivas_c</Filter>
</ClCompile>
<ClCompile Include="..\lib_enc\ivas_corecoder_enc_reconfig.c">
<Filter>enc_ivas_c</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\lib_enc\ivas_stat_enc.h">
......
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Unittests|Win32">
<Configuration>Unittests</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>lib_rend</ProjectName>
<ProjectGuid>{718DE063-A18B-BB72-9150-62B892E6FFA6}</ProjectGuid>
<RootNamespace>evs_dec</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>15.0.27428.2015</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>.\Debug_$(ProjectName)\</OutDir>
<IntDir>.\Debug_$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>libivasrend</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'">
<OutDir>.\Debug_$(ProjectName)\</OutDir>
<IntDir>.\Debug_$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>libivasrend</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>.\Release_$(ProjectName)\</OutDir>
<IntDir>.\Release_$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>libivasrend</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<CustomBuildStep>
<Message />
</CustomBuildStep>
<Midl>
<TypeLibraryName>.\Debug\$(ProjectName).tlb</TypeLibraryName>
<HeaderFileName />
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling />
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader />
<PrecompiledHeaderOutputFile />
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c0c</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>WS2_32.lib; %(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName).lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'">
<CustomBuildStep>
<Message>
</Message>
</CustomBuildStep>
<Midl>
<TypeLibraryName>.\Debug\$(ProjectName).tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c0c</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>WS2_32.lib; %(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName).lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<CustomBuildStep>
<Message />
</CustomBuildStep>
<Midl>
<TypeLibraryName>$(IntDir)$(ProjectName).tlb</TypeLibraryName>
<HeaderFileName />
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>false</IntrinsicFunctions>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader />
<PrecompiledHeaderOutputFile />
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c0c</Culture>
</ResourceCompile>
<Lib>
<AdditionalDependencies>WS2_32.lib; %(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName).lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\lib_rend\ivas_sba_rendering.c" />
<ClCompile Include="..\lib_rend\ivas_allrad_dec.c" />
<ClCompile Include="..\lib_rend\ivas_binauralRenderer.c" />
<ClCompile Include="..\lib_rend\ivas_binaural_reverb.c" />
<ClCompile Include="..\lib_rend\ivas_crend.c" />
<ClCompile Include="..\lib_rend\ivas_efap.c" />
<ClCompile Include="..\lib_rend\ivas_hrtf.c" />
<ClCompile Include="..\lib_rend\ivas_limiter.c" />
<ClCompile Include="..\lib_rend\ivas_ls_custom_dec.c" />
<ClCompile Include="..\lib_rend\ivas_objectRenderer.c" />
<ClCompile Include="..\lib_rend\ivas_objectRenderer_hrFilt.c" />
<ClCompile Include="..\lib_rend\ivas_objectRenderer_mix.c" />
<ClCompile Include="..\lib_rend\ivas_objectRenderer_sfx.c" />
<ClCompile Include="..\lib_rend\ivas_objectRenderer_sources.c" />
<ClCompile Include="..\lib_rend\ivas_objectRenderer_vec.c" />
<ClCompile Include="..\lib_rend\ivas_orient_trk.c" />
<ClCompile Include="..\lib_rend\ivas_output_init.c" />
<ClCompile Include="..\lib_rend\ivas_render_config.c" />
<ClCompile Include="..\lib_rend\ivas_reverb.c" />
<ClCompile Include="..\lib_rend\ivas_reverb_delay_line.c" />
<ClCompile Include="..\lib_rend\ivas_reverb_fft_filter.c" />
<ClCompile Include="..\lib_rend\ivas_reverb_filter_design.c" />
<ClCompile Include="..\lib_rend\ivas_reverb_iir_filter.c" />
<ClCompile Include="..\lib_rend\ivas_reverb_utils.c" />
<ClCompile Include="..\lib_rend\ivas_rom_binauralRenderer.c" />
<ClCompile Include="..\lib_rend\ivas_rom_TdBinauralRenderer.c" />
<ClCompile Include="..\lib_rend\ivas_rom_binaural_crend_head.c" />
<ClCompile Include="..\lib_rend\ivas_rotation.c" />
<ClCompile Include="..\lib_rend\ivas_rom_rend.c" />
<ClCompile Include="..\lib_rend\lib_rend.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\lib_rend\ivas_lib_rend_internal.h" />
<ClInclude Include="..\lib_rend\ivas_rom_binauralRenderer.h" />
<ClInclude Include="..\lib_rend\ivas_rom_binaural_crend_head.h" />
<ClInclude Include="..\lib_rend\ivas_rom_rend.h" />
<ClInclude Include="..\lib_rend\ivas_rom_TdBinauralRenderer.h" />
<ClInclude Include="..\lib_rend\ivas_stat_rend.h" />
<ClInclude Include="..\lib_rend\lib_rend.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="lib_com.vcxproj">
<Project>{39ec200d-7795-4ff8-b214-b24eda5526ae}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="lib_debug.vcxproj">
<Project>{54509728-928b-44d9-a118-a6f92f08b34f}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties DevPartner_IsInstrumented="0" />
</VisualStudio>
</ProjectExtensions>
</Project>
\ No newline at end of file
......@@ -73,7 +73,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling />
......@@ -93,7 +93,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>
......@@ -117,7 +117,7 @@
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>false</IntrinsicFunctions>
<WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
......@@ -141,6 +141,7 @@
<ClCompile Include="..\lib_util\audio_file_writer.c" />
<ClCompile Include="..\lib_util\bitstream_reader.c" />
<ClCompile Include="..\lib_util\bitstream_writer.c" />
<ClCompile Include="..\lib_util\cmdln_parser.c" />
<ClCompile Include="..\lib_util\cmdl_tools.c" />
<ClCompile Include="..\lib_util\evs_rtp_payload.c" />
<ClCompile Include="..\lib_util\g192.c" />
......@@ -162,6 +163,7 @@
<ClInclude Include="..\lib_util\audio_file_writer.h" />
<ClInclude Include="..\lib_util\bitstream_reader.h" />
<ClInclude Include="..\lib_util\bitstream_writer.h" />
<ClInclude Include="..\lib_util\cmdln_parser.h" />
<ClInclude Include="..\lib_util\cmdl_tools.h" />
<ClInclude Include="..\lib_util\evs_rtp_payload.h" />
<ClInclude Include="..\lib_util\g192.h" />
......
......@@ -9,11 +9,15 @@
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Unittests|Win32">
<Configuration>Unittests</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>prerenderer</ProjectName>
<ProjectGuid>{12b4c8a5-1e06-4e30-b443-d1f916f52b47}</ProjectGuid>
<RootNamespace>prerenderer</RootNamespace>
<ProjectName>renderer</ProjectName>
<ProjectGuid>{12B4C8A5-1E06-4E30-B443-D1F916F52B47}</ProjectGuid>
<RootNamespace>renderer</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
......@@ -23,6 +27,12 @@
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
......@@ -34,27 +44,40 @@
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>15.0.27428.2015</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..</OutDir>
<OutDir>..\</OutDir>
<IntDir>.\Debug_$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>IVAS_rend</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'">
<OutDir>..\</OutDir>
<IntDir>.\Debug_$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>IVAS_prerenderer</TargetName>
<TargetName>IVAS_rend</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..</OutDir>
<OutDir>..\</OutDir>
<IntDir>.\Release_$(ProjectName)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<TargetName>IVAS_prerenderer</TargetName>
<TargetName>IVAS_rend</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
......@@ -63,8 +86,8 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\..\lib_com;..\..\..\lib_debug;..\..\..\lib_dec;..\..\..\lib_enc;..\..\..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling />
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
......@@ -76,7 +99,7 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
......@@ -87,16 +110,64 @@
<OutputFile>$(OutDir)$(TargetName).exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ManifestFile />
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<OptimizeReferences />
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention />
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Unittests|Win32'">
<CustomBuildStep>
<Message>
</Message>
</CustomBuildStep>
<Midl>
<TypeLibraryName>$(IntDir)$(ProjectName).tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<ProgramDataBaseFileName>$(IntDir)$(ProjectName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c0c</Culture>
</ResourceCompile>
<Link>
<AdditionalDependencies>
</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName).exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ManifestFile>
</ManifestFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(ProjectName).pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>$(IntDir)$(ProjectName).tlb</TypeLibraryName>
......@@ -109,8 +180,8 @@
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
<AdditionalIncludeDirectories>..\..\..\lib_com;..\..\..\lib_debug;..\..\..\lib_dec;..\..\..\lib_enc;..\..\..\lib_util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling />
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
......@@ -125,7 +196,7 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<DisableSpecificWarnings>4100;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<DisableSpecificWarnings>%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
......@@ -141,43 +212,30 @@
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention />
<TargetMachine>MachineX86</TargetMachine>
<IgnoreSpecificDefaultLibraries>libcmtd.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Workspace_msvc\lib_debug.vcxproj">
<ClCompile Include="..\apps\renderer.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="lib_debug.vcxproj">
<Project>{54509728-928B-44D9-A118-A6F92F08B34F}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\Workspace_msvc\lib_util.vcxproj">
<ProjectReference Include="lib_util.vcxproj">
<Project>{2FA8F384-0775-F3B7-F8C3-85209222FC70}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\Workspace_msvc\lib_com.vcxproj">
<ProjectReference Include="lib_com.vcxproj">
<Project>{39ec200d-7795-4ff8-b214-b24eda5526ae}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\Workspace_msvc\lib_dec.vcxproj">
<Project>{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}</Project>
<ProjectReference Include="lib_rend.vcxproj">
<Project>{718DE063-A18B-BB72-9150-62B892E6FFA6}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\prerenderer.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_allrad_dec.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_efap.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_dirac_output_synthesis_dec.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_ls_custom_dec.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_vbap.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_rom_dec.c" />
<ClCompile Include="..\..\..\lib_dec\ivas_limiter.c" />
<ClCompile Include="..\..\..\lib_enc\ivas_ism_metadata_enc.c" />
<ClCompile Include="..\..\..\lib_util\ivas_prerenderer.c" />
<ClCompile Include="..\..\..\lib_util\ivas_rom_prerenderer.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\lib_util\ivas_prerenderer.h" />
<ClInclude Include="..\..\..\lib_util\ivas_rom_prerenderer.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
......
......@@ -71,10 +71,14 @@ static
int32_t frame = 0; /* Counter of frames */
#define MIN_NUM_BITS_ACTIVE_FRAME 56
#ifdef REMOVE_SID_HARM_LEFTOVERS
#define NUM_BITS_SID_IVAS_5K2 104
#else
#define NUM_BITS_SID_IVAS_4K4 88
#define NUM_BITS_SID_IVAS_7K8 156
#define NUM_BITS_SID_IVAS_9K3 186
#define NUM_BITS_SID_IVAS_10K2 204
#endif
#define META_LINE_LENGTH 200
#define MAX_FRAME_SIZE ( 48000 / 50 )
#define MAX_NUM_OUTPUT_CHANNELS 16
......@@ -105,20 +109,22 @@ typedef struct
bool hrtfReaderEnabled;
char *hrtfFileName;
IVAS_DEC_INPUT_FORMAT inputFormat;
#ifdef DEBUGGING
bool forceSubframeBinauralization;
IVAS_DEC_FORCED_REND_MODE forcedRendMode;
#endif
bool customLsOutputEnabled;
char *customLsSetupFilename;
int16_t orientation_tracking;
float no_diegetic_pan;
bool renderConfigEnabled;
char *renderConfigFilename;
#ifdef DEBUGGING
bool forceSubframeBinauralization;
IVAS_DEC_FORCED_REND_MODE forcedRendMode;
#ifdef DEBUG_FOA_AGC
FILE *agcBitstream; /* temporary */
#endif
#endif
} DecArguments;
......@@ -128,12 +134,10 @@ typedef struct
static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg );
static void usage_dec( void );
#ifdef DEBUGGING
static int16_t app_own_random( int16_t *seed );
#endif
static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, HeadRotFileReader *headRotReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf );
static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec );
#ifdef DEBUGGING
static int16_t app_own_random( int16_t *seed );
static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec( char *forcedRendModeChar );
#endif
......@@ -350,7 +354,11 @@ int main(
fprintf( stderr, "\nError: input bitstream file %s couldn't be read\n\n", arg.inputBitstreamFilename );
goto cleanup;
}
#ifdef REMOVE_SID_HARM_LEFTOVERS
} while ( bfi || num_bits < MIN_NUM_BITS_ACTIVE_FRAME || num_bits == NUM_BITS_SID_IVAS_5K2 );
#else
} while ( bfi || num_bits < MIN_NUM_BITS_ACTIVE_FRAME || num_bits == NUM_BITS_SID_IVAS_4K4 || num_bits == NUM_BITS_SID_IVAS_7K8 || num_bits == NUM_BITS_SID_IVAS_9K3 || num_bits == NUM_BITS_SID_IVAS_10K2 );
#endif
BS_Reader_Rewind( hBsReader );
......@@ -427,25 +435,25 @@ int main(
/* sanity check */
if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM )
{
fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" );
fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n\n" );
goto cleanup;
}
if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
}
if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK )
{
fprintf( stderr, "Failed to read renderer configuration from file %s\n", arg.renderConfigFilename );
fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename );
goto cleanup;
}
if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n", IVAS_DEC_GetErrorMessage( error ) );
fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) );
goto cleanup;
}
}
......@@ -582,10 +590,10 @@ cleanup:
printf( "\n" );
}
#ifdef DEBUGGING
#ifdef DEBUG_SBA_AUDIO_DUMP
ivas_close_sba_decoder_debug_files( arg.output_Fs, numOutChannels, numTransportChannels, pca_ingest_channels );
#endif
#ifdef DEBUGGING
dbgclose();
#endif
......@@ -689,6 +697,9 @@ static bool parseCmdlIVAS_dec(
arg->forcedRendMode = IVAS_DEC_FORCE_REND_UNFORCED;
arg->forceSubframeBinauralization = false;
#ifdef DEBUG_FOA_AGC
arg->agcBitstream = NULL;
#endif
#endif
arg->output_Fs = 48000;
arg->outputFormat = IVAS_DEC_OUTPUT_MONO;
......@@ -720,9 +731,6 @@ static bool parseCmdlIVAS_dec(
arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192;
arg->no_diegetic_pan = 0.f;
#ifdef DEBUG_FOA_AGC
arg->agcBitstream = NULL;
#endif
/*-----------------------------------------------------------------*
* Initialization
......@@ -791,21 +799,6 @@ static bool parseCmdlIVAS_dec(
arg->jbmOffsetFilename = argv[i];
i++;
}
#ifdef DEBUGGING
else if ( strcmp( argv_to_upper, "-FEC" ) == 0 )
{
ftmp = 0.0f;
if ( sscanf( argv[i + 1], "%f", &ftmp ) != 1 )
{
arg->FEPatterFileName = argv[i + 1];
}
else
{
arg->FER = ftmp;
}
i += 2;
}
#endif
else if ( strcmp( argv_to_upper, "-Q" ) == 0 )
{
arg->quietModeEnabled = true;
......@@ -827,6 +820,19 @@ static bool parseCmdlIVAS_dec(
}
}
#ifdef DEBUGGING
else if ( strcmp( argv_to_upper, "-FEC" ) == 0 )
{
ftmp = 0.0f;
if ( sscanf( argv[i + 1], "%f", &ftmp ) != 1 )
{
arg->FEPatterFileName = argv[i + 1];
}
else
{
arg->FER = ftmp;
}
i += 2;
}
else if ( strcmp( argv_to_upper, "-FORCE" ) == 0 )
{
i++;
......@@ -837,6 +843,11 @@ static bool parseCmdlIVAS_dec(
i++;
}
}
else if ( strcmp( argv_to_upper, "-FORCE_SUBFRAME_BIN" ) == 0 ) /* Force binauralization to subframe (5 ms) resolution */
{
arg->forceSubframeBinauralization = true;
i++;
}
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
/*-----------------------------------------------------------------*
......@@ -948,13 +959,6 @@ static bool parseCmdlIVAS_dec(
}
i++;
}
#ifdef DEBUGGING
else if ( strcmp( argv_to_upper, "-FORCE_SUBFRAME_BIN" ) == 0 ) /* Force binauralization to subframe (5 ms) resolution */
{
arg->forceSubframeBinauralization = true;
i++;
}
#endif
/*-----------------------------------------------------------------*
* Option not recognized
......
......@@ -72,6 +72,7 @@ typedef union _EncInputFormatConfig
{
/* MONO details */
bool stereoToMonoDownmix;
#ifdef DEBUGGING
/* STEREO details */
IVAS_ENC_STEREO_MODE stereoMode;
......@@ -83,16 +84,20 @@ typedef union _EncInputFormatConfig
int16_t numObjects;
const char *metadataFiles[IVAS_MAX_NUM_OBJECTS];
} ism;
/* SBA details */
struct EncSbaConfig
{
IVAS_ENC_SBA_ORDER order;
bool isPlanar;
} sba;
/* MASA details */
IVAS_ENC_MASA_VARIANT masaVariant;
/* MC details */
IVAS_ENC_MC_LAYOUT mcLayout;
} EncInputFormatConfig;
/* Struct for storing cmdln arguments */
......@@ -112,22 +117,24 @@ typedef struct
bool quietModeEnabled;
bool delayCompensationEnabled;
const char *masaMetadataFile;
#ifdef DEBUGGING
IVAS_ENC_FORCED_MODE forcedMode;
const char *forcedModeFile;
#endif
IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig;
const char *ca_config_file;
bool mimeOutput;
bool agc;
bool pca;
#ifdef DEBUGGING
IVAS_ENC_FORCED_MODE forcedMode;
const char *forcedModeFile;
#ifdef DEBUG_AGC_ENCODER_CMD_OPTION
IVAS_ENC_AGC agc;
#endif
#ifdef DEBUG_FOA_AGC
FILE *agcBitstream; /* temporary */
#endif
#ifdef DEBUG_SBA
const char *dbg_file_tag;
#endif
#endif
bool pca;
} EncArguments;
......@@ -212,17 +219,13 @@ int main(
int16_t *pcmBuf = NULL;
#ifdef DEBUGGING
FILE *f_forcedModeProfile = NULL;
#endif
#ifdef DEBUG_SBA
int16_t numTransportChannels = 1;
#endif
#ifdef WMOPS
size_t SRAM_size = 0;
#endif
#ifdef WMOPS
size_t SRAM_size = 0;
reset_wmops();
reset_stack();
#endif
......@@ -262,12 +265,18 @@ int main(
/*------------------------------------------------------------------------------------------*
* Open input audio file
*------------------------------------------------------------------------------------------*/
if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, arg.inputFs ) != IVAS_ERR_OK )
int32_t inFileSampleRate = 0;
if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, &inFileSampleRate ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename );
goto cleanup;
}
if ( inFileSampleRate != 0 && /* inFileSampleRate will remain zero if input file is raw PCM */
inFileSampleRate != arg.inputFs )
{
fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename );
goto cleanup;
}
/*------------------------------------------------------------------------------------------*
* Open output bitstream file
......@@ -440,11 +449,25 @@ int main(
}
break;
case IVAS_ENC_INPUT_SBA:
if ( ( error =
IVAS_ENC_ConfigureForAmbisonics(
hIvasEnc,
arg.inputFs,
totalBitrate,
arg.max_bwidth_user,
bandwidth,
arg.dtxConfig,
arg.inputFormatConfig.sba.order,
arg.inputFormatConfig.sba.isPlanar,
#ifdef DEBUG_AGC_ENCODER_CMD_OPTION
arg.agc,
#endif
arg.pca
#ifdef DEBUG_SBA_AUDIO_DUMP
if ( ( error = IVAS_ENC_ConfigureForAmbisonics( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.sba.order, arg.inputFormatConfig.sba.isPlanar, arg.agc, arg.pca, &numTransportChannels ) ) != IVAS_ERR_OK )
#else
if ( ( error = IVAS_ENC_ConfigureForAmbisonics( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.sba.order, arg.inputFormatConfig.sba.isPlanar, arg.agc, arg.pca ) ) != IVAS_ERR_OK )
,
&numTransportChannels
#endif
) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nIVAS_ENC_ConfigureForAmbisonics failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
goto cleanup;
......@@ -804,13 +827,6 @@ cleanup:
fclose( f_bitrateProfile );
}
#ifdef DEBUGGING
if ( f_forcedModeProfile )
{
fclose( f_forcedModeProfile );
}
#endif
IVAS_ENC_Close( &hIvasEnc );
#ifdef RAM_COUNTING_TOOL
......@@ -826,13 +842,18 @@ cleanup:
#ifdef DEBUGGING
dbgclose();
#endif
if ( f_forcedModeProfile )
{
fclose( f_forcedModeProfile );
}
#ifdef DEBUG_SBA
ivas_close_sba_encoder_debug_files();
#ifdef DEBUG_AGC
ivas_close_agc_debug_files();
#endif
#endif
#endif
return mainFailed ? -1 : 0;
......@@ -862,22 +883,24 @@ static void initArgStruct( EncArguments *arg )
arg->quietModeEnabled = false;
arg->delayCompensationEnabled = true;
arg->masaMetadataFile = NULL;
#ifdef DEBUGGING
arg->forcedMode = IVAS_ENC_FORCE_UNFORCED;
arg->forcedModeFile = NULL;
#endif
arg->caConfig = IVAS_ENC_GetDefaultChannelAwareConfig();
arg->ca_config_file = NULL;
arg->mimeOutput = false;
arg->agc = IVAS_DEFAULT_AGC;
arg->pca = false;
#ifdef DEBUGGING
arg->forcedMode = IVAS_ENC_FORCE_UNFORCED;
arg->forcedModeFile = NULL;
#ifdef DEBUG_AGC_ENCODER_CMD_OPTION
arg->agc = IVAS_ENC_AGC_UNDEFINED;
#endif
#ifdef DEBUG_FOA_AGC
arg->agcBitstream = NULL;
#endif
#ifdef DEBUG_SBA
arg->dbg_file_tag = NULL;
#endif
#endif
arg->pca = false;
return;
}
......@@ -1039,6 +1062,54 @@ static bool parseCmdlIVAS_enc(
}
#endif /* #ifdef DEBUG_MODE_INFO_TWEAK */
#endif /* #ifdef DEBUG_MODE_INFO */
#ifdef DEBUG_AGC_ENCODER_CMD_OPTION
/*-----------------------------------------------------------------*
* IVAS SPAR AGC option
*-----------------------------------------------------------------*/
else if ( strcmp( argv_to_upper, "-AGC" ) == 0 )
{
i++;
if ( i < argc - 4 )
{
arg->agc = ( atoi( argv[i] ) ) ? IVAS_ENC_AGC_ENABLED : IVAS_ENC_AGC_DISABLED;
if ( argv[i] == NULL || atoi( argv[i] ) < 0 || atoi( argv[i] ) > 1 )
{
fprintf( stderr, "Error: wrong adaptive gain control option specified (%d), expected 0 or 1\n\n", (int32_t) atoi( argv[i] ) );
usage_enc();
return false;
}
i++;
}
else
{
fprintf( stderr, "Error: unspecified adaptive gain control option\n\n" );
usage_enc();
return false;
}
}
#endif
#ifdef DEBUG_SBA
/*-----------------------------------------------------------------*
* IVAS SPAR debug files tag
*-----------------------------------------------------------------*/
else if ( strcmp( argv_to_upper, "-TAG" ) == 0 )
{
i++;
if ( i < argc - 4 )
{
arg->dbg_file_tag = argv[i];
++i;
}
else
{
fprintf( stderr, "Error: [IVAS SPAR Encoder] unspecified tag value \n\n" );
usage_enc();
return false;
}
}
#endif
#endif /* #ifdef DEBUGGING */
/*-----------------------------------------------------------------*
......@@ -1376,27 +1447,6 @@ static bool parseCmdlIVAS_enc(
arg->inputFormatConfig.stereoToMonoDownmix = true;
i++;
}
else if ( strcmp( argv_to_upper, "-AGC" ) == 0 )
{
i++;
if ( i < argc - 4 )
{
arg->agc = (int16_t) atoi( argv[i] );
if ( argv[i] == NULL || atoi( argv[i] ) < 0 || atoi( argv[i] ) > 1 )
{
fprintf( stderr, "Error: wrong adaptive gain control option specified (%d), expected 0 or 1\n\n", (int32_t) atoi( argv[i] ) );
usage_enc();
return false;
}
i++;
}
else
{
fprintf( stderr, "Error: unspecified adaptive gain control option\n\n" );
usage_enc();
return false;
}
}
else if ( strcmp( argv_to_upper, "-BYPASS" ) == 0 ) // VE: should be renamed to "-pca"
{
i++;
......@@ -1430,26 +1480,6 @@ static bool parseCmdlIVAS_enc(
return false;
}
}
#ifdef DEBUG_SBA
/*-----------------------------------------------------------------*
* IVAS SPAR debug files tag
*-----------------------------------------------------------------*/
else if ( strcmp( argv_to_upper, "-TAG" ) == 0 )
{
i++;
if ( i < argc - 4 )
{
arg->dbg_file_tag = argv[i];
++i;
}
else
{
fprintf( stderr, "Error: [IVAS SPAR Encoder] unspecified tag value \n\n" );
usage_enc();
return false;
}
}
#endif
/*-----------------------------------------------------------------*
* Option not recognized
......@@ -1633,14 +1663,18 @@ static void usage_enc( void )
fprintf( stdout, " The encoder produces TS26.445 Annex.2.6 Mime Storage Format, (not RFC4867 Mime Format).\n" );
fprintf( stdout, " default output bitstream file format is G.192\n" );
#ifdef DEBUG_SBA
fprintf( stdout, "-tag : Tag name for intermediate debug files\n" );
#endif
fprintf( stdout, "-agc op : SBA Adaptive gain control, op = (0, 1), by default op is 0 or deactivated\n" );
fprintf( stdout, "-bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1\n" );
#ifdef DEBUGGING
fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" );
fprintf( stdout, " alternatively, T can be a text file where each line contains \"nb_frames T\"\n" );
#ifdef DEBUG_SBA
fprintf( stdout, "-tag : Tag name for intermediate debug files\n" );
#endif
#ifdef DEBUG_AGC_ENCODER_CMD_OPTION
fprintf( stdout, "-agc op : SBA Adaptive gain control, op = (0, 1). \n" );
fprintf( stdout, " By default op is 1 (activated) for bitrates between 24400 and 32000,\n" );
fprintf( stdout, " otherwise it is 0 (deactivated) for all other bitrates\n" );
#endif
#ifdef DEBUG_MODE_INFO
#ifdef DEBUG_MODE_INFO_TWEAK
fprintf( stdout, "-info <folder> : specify subfolder name for debug output\n" );
......
/******************************************************************************************************
(C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository. All Rights Reserved.
This software is protected by copyright law and by international treaties.
The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
contributors to this repository retain full ownership rights in their respective contributions in
the software. This notice grants no license of any kind, including but not limited to patent
license, nor is any license granted by implication, estoppel or otherwise.
Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
contributions.
This software is provided "AS IS", without any express or implied warranties. The software is in the
development stage. It is intended exclusively for experts who have experience with such software and
solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
and fitness for a particular purpose are hereby disclaimed and excluded.
Any dispute, controversy or claim arising under or in relation to providing this software shall be
submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
the United Nations Convention on Contracts on the International Sales of Goods.
*******************************************************************************************************/
#include "options.h"
#include "debug.h"
#include "audio_file_reader.h"
#include "audio_file_writer.h"
#include "cmdl_tools.h"
#include "cmdln_parser.h"
#include "common_api_types.h"
#include "head_rotation_file_reader.h"
#include "hrtf_file_reader.h"
#include "ism_file_reader.h"
#include "lib_rend.h"
#include "ls_custom_file_reader.h"
#include "masa_file_reader.h"
#include "prot.h"
#include "render_config_reader.h"
#ifdef WMOPS
#include "PROM_Size_lib_rend.h"
#include "wmops.h"
#endif
#ifdef RAM_COUNTING_TOOL
#include "mem_count.h"
#endif
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#ifdef EXT_RENDERER
#ifndef count_malloc
#ifdef RAM_COUNTING_TOOL
#define count_malloc( n1 ) MALLOC_FCT_CALL( n1 )
#define count_calloc( n1, n2 ) CALLOC_FCT_CALL( n1, n2 )
#define count_free( ptr ) FREE_FCT_CALL( ptr )
#else
#define count_malloc( n1 ) malloc( n1 )
#define count_calloc( n1, n2 ) calloc( n1, n2 )
#define count_free( ptr ) free( ptr )
#endif
#endif
#ifndef min
#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )
#endif
#ifndef max
#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) )
#endif
#define RENDERER_MAX_CLI_ARG_LENGTH ( FILENAME_MAX )
#define RENDERER_MAX_METADATA_LENGTH 8192
#define RENDERER_MAX_METADATA_LINE_LENGTH 1024
#if !defined( DEBUGGING ) && !defined( WMOPS )
static
#endif
int32_t frame = 0;
#ifdef _WIN32
#define SEP_FOLDER '\\'
#else
#define SEP_FOLDER '/'
#endif
#ifdef WMOPS
void print_stack_call_tree( void );
int Const_Data_Size_ivas_rom_rend( void );
extern int16_t *ptr_base_stack;
extern int16_t *ptr_max_stack;
extern int32_t wc_frame;
extern char location_max_stack[256];
/*------------------------------------------------------------------------------------------*
* Function to print complexity & memory estimates
*------------------------------------------------------------------------------------------*/
static void print_mem_renderer( size_t SRAM_size )
{
fprintf( stdout, "\n\n --- Renderer memory usage --- \n\n" );
fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend );
fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame );
fprintf( stdout, "Table ROM size(renderer): %d words\n", ( Const_Data_Size_ivas_rom_rend() ) / sizeof( float ) );
fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) );
#ifdef RAM_COUNTING_TOOL
fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size );
#endif
print_stack_call_tree();
fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" );
fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" );
fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" );
fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" );
}
#endif
typedef struct
{
uint32_t frameCounter;
uint16_t numObjects;
IsmFileReader *ismReaders[RENDERER_MAX_ISM_INPUTS];
uint32_t numPositions[RENDERER_MAX_ISM_INPUTS];
IVAS_REND_AudioObjectPosition *positions[RENDERER_MAX_ISM_INPUTS]; /* size: [RENDERER_MAX_ISM_INPUTS][numPositions[object_index]] */
uint16_t *positionDurations[RENDERER_MAX_ISM_INPUTS]; /* size: [RENDERER_MAX_ISM_INPUTS][numPositions[object_index]] */
uint32_t currentPositionIdxs[RENDERER_MAX_ISM_INPUTS]; /* Index of current position as listed in the metadata file */
uint16_t durationCounters[RENDERER_MAX_ISM_INPUTS]; /* Number of frames spent at current position */
} IsmPositionProvider;
typedef struct
{
IVAS_REND_AudioConfig audioConfig;
int32_t inputChannelIndex;
float gain_dB;
} RendererInput;
typedef struct
{
IVAS_REND_AudioObjectPosition positions[RENDERER_MAX_ISM_INPUTS];
int16_t numObjects;
} ObjectPositionBuffer;
typedef struct
{
RendererInput audioObjects[RENDERER_MAX_ISM_INPUTS];
uint16_t numAudioObjects;
RendererInput multiChannelBuses[RENDERER_MAX_MC_INPUTS];
uint16_t numMultiChannelBuses;
RendererInput ambisonicsBuses[RENDERER_MAX_SBA_INPUTS];
uint16_t numAmbisonicsBuses;
IVAS_CUSTOM_LS_DATA inSetupCustom;
RendererInput masaBuses[RENDERER_MAX_MASA_INPUTS];
uint16_t numMasaBuses;
} InputConfig;
typedef struct
{
IVAS_REND_AudioConfig audioConfig;
IVAS_CUSTOM_LS_DATA outSetupCustom;
} OutputConfig;
typedef struct
{
char executableName[RENDERER_MAX_CLI_ARG_LENGTH];
char inputFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char outputFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
int32_t sampleRate;
InputConfig inConfig;
OutputConfig outConfig;
char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH];
int16_t numInMetadataFiles;
char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char customHrtfFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
char renderConfigFilePath[RENDERER_MAX_CLI_ARG_LENGTH];
int8_t orientationTracking;
float noDiegeticPan;
bool delayCompensationEnabled;
bool quietModeEnabled;
bool sceneDescriptionInput;
float inputGainGlobal; /* Linear gain (not in dB) */
} CmdlnArgs;
typedef enum
{
CmdLnOptionId_inputFile = 1,
CmdLnOptionId_inputFormat,
CmdLnOptionId_outputFile,
CmdLnOptionId_outputFormat,
CmdLnOptionId_sampleRate,
CmdLnOptionId_trajFile,
CmdLnOptionId_customHrtfFile,
CmdLnOptionId_renderConfigFile,
CmdLnOptionId_noDiegeticPan,
CmdLnOptionId_orientationTracking,
CmdLnOptionId_customLfeRouting,
CmdLnOptionId_noDelayCmp,
CmdLnOptionId_quietModeEnabled,
CmdLnOptionId_inputMetadata,
CmdLnOptionId_listFormats,
CmdLnOptionId_inputGain,
} CmdLnOptionId;
static const CmdLnParser_Option cliOptions[] = {
{
.id = CmdLnOptionId_inputFile,
.match = "input_file",
.matchShort = "i",
.description = "Path to the input file (WAV, raw PCM or scene description file)",
},
{
.id = CmdLnOptionId_inputFormat,
.match = "input_format",
.matchShort = "if",
.description = "Audio format of input file (e.g. 5_1 or HOA3 or META, use -l for a list)",
},
{
.id = CmdLnOptionId_inputMetadata,
.match = "input_metadata",
.matchShort = "im",
.description = "Space-separated list of path to metadata files for ISM or MASA inputs",
},
{
.id = CmdLnOptionId_outputFile,
.match = "output_file",
.matchShort = "o",
.description = "Path to the output file",
},
{
.id = CmdLnOptionId_outputFormat,
.match = "output_format",
.matchShort = "of",
.description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file",
},
{
.id = CmdLnOptionId_sampleRate,
.match = "sample_rate",
.matchShort = "fs",
.description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs", /* TODO(sgi): Add sampling rate to scene description files */
},
{
.id = CmdLnOptionId_trajFile,
.match = "trajectory_file",
.matchShort = "tf",
.description = "Head rotation trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)",
},
{
.id = CmdLnOptionId_customHrtfFile,
.match = "custom_hrtf",
.matchShort = "hrtf",
.description = "Custom HRTF file for binaural rendering (only for BINAURAL and BINAURAL_ROOM outputs)",
},
{
.id = CmdLnOptionId_renderConfigFile,
.match = "render_config",
.matchShort = "rc",
.description = "Binaural renderer configuration file (only for BINAURAL and BINAURAL_ROOM outputs)",
},
{
.id = CmdLnOptionId_noDiegeticPan,
.match = "no_diegetic_pan",
.matchShort = "ndp",
.description = "Panning mono no diegetic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle\n(todo: implementation)",
},
{
.id = CmdLnOptionId_orientationTracking,
.match = "tracking_type",
.matchShort = "otr",
.description = "Head orientation tracking type: 'ref' or 'avg' (only for BINAURAL and BINAURAL_ROOM) (todo: check implementation)",
},
{
/* TODO(sgi): Replace with more configurable input, e.g. ask for a list of triplets: (gain, azimuth, elevation) to place LFE signal */
/* rename to "lfeHandling" */
.id = CmdLnOptionId_customLfeRouting,
.match = "neverDropLfe",
.matchShort = "ndl",
.description = "[flag] If set, renderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE",
},
{
.id = CmdLnOptionId_noDelayCmp,
.match = "no_delay_cmp",
.matchShort = "ndc",
.description = "[flag] Turn off delay compensation",
},
{
.id = CmdLnOptionId_quietModeEnabled,
.match = "quiet",
.matchShort = "q",
.description = "[flag] Limit printouts to terminal",
},
{
.id = CmdLnOptionId_inputGain,
.match = "gain",
.matchShort = "g",
.description = "Input gain (linear, not in dB) to be applied to input audio file",
},
{
.id = CmdLnOptionId_listFormats,
.match = "list",
.matchShort = "l",
.description = "List supported audio formats",
},
};
static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option );
static IVAS_REND_AudioConfig ambisonicsOrderToEnum(
const int16_t order );
static void parseSceneDescriptionFile(
char *path,
char *audioFilePath,
InputConfig *inConfig,
IsmPositionProvider *positionProvider,
MasaFileReader **masaReaders );
static ivas_error parseCustomLayoutFile(
const char *filePath,
IVAS_CUSTOM_LS_DATA *pLsSetupCustom );
static CmdlnArgs parseCmdlnArgs(
const int argc,
char **argv );
static IsmPositionProvider *IsmPositionProvider_open(
void );
static void IsmPositionProvider_getNextFrame(
IsmPositionProvider *positionProvider,
ObjectPositionBuffer *objectMetadataBuffer );
static void IsmPositionProvider_close(
IsmPositionProvider *positionProvider );
static void readFromShorthandMetadata(
IsmPositionProvider *positionProvider,
ObjectPositionBuffer *objectMetadataBuffer,
const uint32_t objIdx );
void getMetadataFromFileReader(
IsmFileReader *ismReader,
ObjectPositionBuffer *objectMetadataBuffer,
const uint32_t objIdx );
static void splitConfigFile(
const char *mdfFilePath,
char *metadataString,
uint32_t *metadataStringLength,
char *wavFileName,
uint32_t *wavFileNameLength );
static char *readNextMetadataChunk(
char *line,
const char *delimiter );
static void parseUint8(
const char *line,
uint8_t *ret );
static void parseUint16(
const char *line,
uint16_t *ret );
static int8_t parseUint32(
const char *line,
uint32_t *ret );
static int8_t parseInt32(
const char *line,
int32_t *ret );
static void parseObjectPosition(
char *line,
IVAS_REND_AudioObjectPosition *position,
uint16_t *positionDuration );
static void parseMetadata(
char *metadataString,
char *inDir,
InputConfig *inConfig,
IsmPositionProvider *positionProvider,
MasaFileReader **masaReaders );
static void convert_backslash( char *str );
static void remove_cr( char *str );
static void clearString( char *str );
static bool isEmptyString( const char *str );
static void printSupportedAudioConfigs( void );
static IVAS_REND_AudioConfig parseAudioConfig( const char *configString );
static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer );
static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer );
static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, const int16_t chBeginIdx, const int16_t numChannels )
{
IVAS_REND_ReadOnlyAudioBuffer subBuffer;
subBuffer.config = buffer.config;
subBuffer.config.numChannels = numChannels;
subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx;
return subBuffer;
}
static int16_t getTotalNumInChannels(
IVAS_REND_HANDLE hIvasRend,
IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS],
IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS],
IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] )
{
int16_t totalNumInChannels = 0;
int16_t i, numInputChannels;
ivas_error error;
for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i )
{
if ( mcIds[i] == 0 )
{
/* Skip inactive inputs */
continue;
}
if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numInputChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
totalNumInChannels += numInputChannels;
}
for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i )
{
if ( ismIds[i] == 0 )
{
/* Skip inactive inputs */
continue;
}
if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, ismIds[i], &numInputChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
totalNumInChannels += numInputChannels;
}
for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i )
{
if ( sbaIds[i] == 0 )
{
/* Skip inactive inputs */
continue;
}
if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numInputChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
totalNumInChannels += numInputChannels;
}
return totalNumInChannels;
}
static void setupWithSingleFormatInput(
CmdlnArgs args,
char *audioFilePath,
IsmPositionProvider *positionProvider,
MasaFileReader **masaReaders )
{
/* With single-format input, inputFilePath is the path to input audio file. */
strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 );
/* Depending on input format, prepare metadata reading for ISM or MASA */
if ( args.inConfig.numMasaBuses != 0 )
{
if ( args.inConfig.numMasaBuses != args.numInMetadataFiles )
{
fprintf( stderr, "Error: all MASA inputs must have a corresponding metadata file" );
exit( -1 );
}
for ( int32_t i = 0; i < args.numInMetadataFiles; ++i )
{
masaReaders[i] = MasaFileReader_open( args.inMetadataFilePaths[i] );
if ( masaReaders[i] == NULL )
{
fprintf( stderr, "Could not open MASA metadata file %s\n", args.inMetadataFilePaths[i] );
exit( -1 );
}
}
}
else if ( args.inConfig.numAudioObjects != 0 )
{
positionProvider->numObjects = args.inConfig.numAudioObjects;
for ( int16_t i = 0; i < positionProvider->numObjects; ++i )
{
/* It is allowed on CLI to have no metadata for an ISM input - skip opening if string is empty or contains "NULL" */
char charBuf[FILENAME_MAX];
strncpy( charBuf, args.inMetadataFilePaths[i], min( FILENAME_MAX, RENDERER_MAX_CLI_ARG_LENGTH ) - 1 );
to_upper( charBuf );
if ( isEmptyString( args.inMetadataFilePaths[i] ) || strncmp( charBuf, "NULL", 4 ) == 0 )
{
continue;
}
positionProvider->ismReaders[i] = IsmFileReader_open( args.inMetadataFilePaths[i] );
if ( positionProvider->ismReaders[i] == NULL )
{
fprintf( stderr, "Could not open object metadata file %s\n", args.inMetadataFilePaths[i] );
exit( -1 );
}
}
}
}
static float dBToLin(
const float gain_dB )
{
return powf( 10.0f, gain_dB / 20.0f );
}
/* ============================================================================ */
int main(
int argc,
char **argv )
{
IVAS_REND_HANDLE hIvasRend;
HeadRotFileReader *headRotReader = NULL;
hrtfFileReader *hrtfFileReader = NULL;
IsmPositionProvider *positionProvider;
RenderConfigReader *renderConfigReader = NULL;
MasaFileReader *masaReaders[RENDERER_MAX_MASA_INPUTS];
IVAS_MASA_METADATA_HANDLE hMasaMetadata[RENDERER_MAX_MASA_INPUTS];
char audioFilePath[FILENAME_MAX];
AudioFileReader *audioReader = NULL;
AudioFileWriter *audioWriter;
int32_t inBufferSize;
int32_t outBufferSize;
int16_t *inpInt16Buffer;
float *inFloatBuffer;
int16_t *outInt16Buffer;
float *outFloatBuffer;
IVAS_REND_AudioBuffer inBuffer;
IVAS_REND_AudioBuffer outBuffer;
int16_t numSamplesRead;
int16_t delayNumSamples = -1;
int16_t delayNumSamples_orig = 0;
int16_t zeroPad = 0;
int32_t delayTimeScale = 0;
int16_t i, numChannels;
ivas_error error = IVAS_ERR_OK;
#ifdef WMOPS
size_t SRAM_size;
#endif
#ifdef WMOPS
reset_wmops();
reset_stack();
#endif
#ifdef RAM_COUNTING_TOOL
mem_count_init( 0, USE_32BITS );
#endif
for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i )
{
masaReaders[i] = NULL;
hMasaMetadata[i] = NULL;
}
CmdlnArgs args = parseCmdlnArgs( argc, argv );
positionProvider = IsmPositionProvider_open();
convert_backslash( args.inputFilePath );
convert_backslash( args.outputFilePath );
convert_backslash( args.headRotationFilePath );
if ( !isEmptyString( args.headRotationFilePath ) )
{
HeadRotationFileReader_open( args.headRotationFilePath, &headRotReader );
}
if ( !isEmptyString( args.customHrtfFilePath ) )
{
hrtfFileReader_open( args.customHrtfFilePath, &hrtfFileReader );
}
if ( !isEmptyString( args.renderConfigFilePath ) )
{
RenderConfigReader_open( args.renderConfigFilePath, &renderConfigReader );
}
/* Initialize main input files, i.e. audio and metadata */
if ( args.sceneDescriptionInput )
{
/* With scene description input, inputFilePath is the path to the scene description file. Parse it. */
parseSceneDescriptionFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider, masaReaders );
}
else
{
/* With single-format input, all information is given on command line. */
setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders );
}
int32_t inFileSampleRate = 0;
if ( AudioFileReader_open( &audioReader, audioFilePath, &inFileSampleRate ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error opening file: %s\n", audioFilePath );
exit( -1 );
}
if ( args.sampleRate == 0 && inFileSampleRate == 0 )
{
fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" );
exit( -1 );
}
if ( args.sampleRate != 0 && inFileSampleRate != 0 && args.sampleRate != inFileSampleRate )
{
fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath );
exit( -1 );
}
if ( args.sampleRate == 0 )
{
args.sampleRate = inFileSampleRate;
}
const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 );
IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 };
IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 };
IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] = { 0 };
if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
/* === Configure === */
if ( ( error = IVAS_REND_InitConfig( hIvasRend, strlen( args.renderConfigFilePath ) != 0 ) ) != IVAS_ERR_OK )
{
exit( -1 );
}
if ( args.renderConfigFilePath[0] != '\0' )
{
IVAS_RENDER_CONFIG_DATA renderConfig;
/* sanity check */
if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM )
{
fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" );
exit( -1 );
}
if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" );
exit( -1 );
}
if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK )
{
fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath );
exit( -1 );
}
if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" );
exit( -1 );
}
}
/* Set up output custom layout configuration */
if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM )
{
if ( ( error = IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( hIvasRend, args.outConfig.outSetupCustom ) ) != IVAS_ERR_OK )
{
return error;
}
}
for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i )
{
if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
if ( ( error = IVAS_REND_SetInputGain( hIvasRend, mcIds[i], args.inputGainGlobal * dBToLin( args.inConfig.multiChannelBuses[i].gain_dB ) ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
/* TODO(sgi): Command line only supports one custom LS input for now, extend */
if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM )
{
if ( ( error = IVAS_REND_ConfigureCustomInputLoudspeakerLayout( hIvasRend, mcIds[i], args.inConfig.inSetupCustom ) ) != IVAS_ERR_OK )
{
return error;
}
}
/* TODO(sgi): Test custom LFE routing here */
}
for ( i = 0; i < args.inConfig.numAudioObjects; ++i )
{
if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_REND_AUDIO_CONFIG_OBJECT, &ismIds[i] ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
if ( ( error = IVAS_REND_SetInputGain( hIvasRend, ismIds[i], args.inputGainGlobal * dBToLin( args.inConfig.audioObjects[i].gain_dB ) ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
}
for ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i )
{
if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
if ( ( error = IVAS_REND_SetInputGain( hIvasRend, sbaIds[i], args.inputGainGlobal * dBToLin( args.inConfig.ambisonicsBuses[i].gain_dB ) ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
}
const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds );
if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */
&& totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) )
{
fprintf( stderr, "Number of channels in input file does not match selected configuration\n" );
exit( -1 );
}
for ( i = 0; i < args.inConfig.numMasaBuses; ++i )
{
if ( masaReaders[i] != NULL )
{
hMasaMetadata[i] = MasaFileReader_getMetadataHandle( masaReaders[i] );
}
}
int16_t numOutChannels;
if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK )
{
fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath );
exit( -1 );
}
#ifdef DEC_TO_REND_FLOAT_DUMP
printf( "Warning: Renderer executable built with DEC_TO_REND_FLOAT_DUMP enabled!\n" );
printf( " Float dump file (./float_out.wav) will be forced as input.\n" );
#endif
inBufferSize = frameSize_smpls * totalNumInChannels;
outBufferSize = frameSize_smpls * numOutChannels;
inpInt16Buffer = count_malloc( inBufferSize * sizeof( int16_t ) );
inFloatBuffer = count_malloc( inBufferSize * sizeof( float ) );
outInt16Buffer = count_malloc( outBufferSize * sizeof( int16_t ) );
outFloatBuffer = count_malloc( outBufferSize * sizeof( float ) );
inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls;
inBuffer.config.numChannels = (int16_t) totalNumInChannels;
inBuffer.data = inFloatBuffer;
outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls;
outBuffer.config.numChannels = (int16_t) numOutChannels;
outBuffer.data = outFloatBuffer;
#ifdef WMOPS
reset_wmops();
#endif
if ( !args.quietModeEnabled )
{
fprintf( stdout, "\n------ Running the renderer ------\n\n" );
fprintf( stdout, "Frames processed: " );
}
else
{
fprintf( stdout, "\n\n-- Start the renderer (quiet mode) --\n\n" );
}
while ( 1 )
{
int16_t num_in_channels;
num_in_channels = inBuffer.config.numChannels;
/* 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 )
{
/* end of input data */
break;
}
/* Convert from int to float and from interleaved to packed */
convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer );
#ifdef DEC_TO_REND_FLOAT_DUMP
/* Overwrite from dump file */
float tmp[960 * 16];
dbgread( tmp, sizeof( float ), numSamplesRead, "./float_out.raw" );
/* Conversion from interleaved to packed still necessary */
for ( int32_t i = 0; i < numSamplesRead / num_in_channels; ++i )
{
for ( int32_t c = 0; c < num_in_channels; ++c )
{
inFloatBuffer[c * frameSize_smpls + i] = tmp[i * num_in_channels + c];
}
}
#endif
for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i )
{
if ( masaReaders[i] != NULL )
{
MasaFileReader_readNextFrame( masaReaders[i] );
/* TODO: Feed MASA metadata here once MASA inputs are supported.
For now avoid unused var warning */
(void) hMasaMetadata;
}
}
ObjectPositionBuffer mtdBuffer;
IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer );
/* Read from head rotation trajectory file if specified */
if ( headRotReader != NULL )
{
IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME];
HeadRotationFileReading( headRotReader, quatBuffer, frame );
IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer );
}
else
{
IVAS_REND_SetHeadRotation( hIvasRend, NULL );
}
for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i )
{
if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.multiChannelBuses[i].inputChannelIndex, numChannels );
if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, mcIds[i], tmpBuffer ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
}
for ( i = 0; i < args.inConfig.numAudioObjects; ++i )
{
IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.audioObjects[i].inputChannelIndex, 1 );
if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
if ( ( error = IVAS_REND_FeedInputObjectMetadata( hIvasRend, ismIds[i], mtdBuffer.positions[i] ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
}
for ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i )
{
if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.ambisonicsBuses[i].inputChannelIndex, numChannels );
if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, sbaIds[i], tmpBuffer ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
exit( -1 );
}
}
IVAS_REND_GetSamples( hIvasRend, outBuffer );
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, frameSize_smpls, num_out_channels, outInt16Buffer );
if ( delayNumSamples == -1 )
{
if ( args.delayCompensationEnabled )
{
if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nUnable to get delay of renderer!\n" );
exit( -1 );
}
delayNumSamples_orig = delayNumSamples;
}
else
{
delayNumSamples = 0;
}
zeroPad = delayNumSamples;
}
if ( delayNumSamples < outBufferSize )
{
if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath );
exit( -1 );
}
delayNumSamples = 0;
}
else
{
delayNumSamples -= (int16_t) outBufferSize;
}
frame++;
if ( !args.quietModeEnabled )
{
fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame );
}
#ifdef WMOPS
update_wmops();
#endif
}
/* add zeros at the end to have equal length of synthesized signals */
memset( outInt16Buffer, 0, zeroPad * outBuffer.config.numChannels * sizeof( int16_t ) );
if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPad * outBuffer.config.numChannels ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nOutput audio file writer error\n" );
exit( -1 );
}
if ( !args.quietModeEnabled && args.delayCompensationEnabled )
{
fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale );
}
fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame );
#ifdef DEBUGGING
int32_t cnt_frames_limited, noClipping;
if ( ( cnt_frames_limited = IVAS_REND_GetCntFramesLimited( hIvasRend ) ) > 0 )
{
fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited );
}
if ( ( noClipping = IVAS_REND_GetNoCLipping( hIvasRend ) ) > 0 )
{
fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping );
}
#endif
/* === Close === */
count_free( inpInt16Buffer );
count_free( inFloatBuffer );
count_free( outInt16Buffer );
count_free( outFloatBuffer );
for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i )
{
MasaFileReader_close( &masaReaders[i] );
}
AudioFileReader_close( &audioReader );
AudioFileWriter_close( &audioWriter );
HeadRotationFileReader_close( &headRotReader );
hrtfFileReader_close( &hrtfFileReader );
IVAS_REND_Close( &hIvasRend );
IsmPositionProvider_close( positionProvider );
RenderConfigReader_close( &renderConfigReader );
#ifdef RAM_COUNTING_TOOL
#ifdef WMOPS
SRAM_size =
#endif
mem_count_summary( USE_DEFAULT );
#endif
#ifdef WMOPS
print_wmops();
print_mem_renderer( SRAM_size );
#endif
return 0;
}
static IVAS_REND_AudioConfig ambisonicsOrderToEnum(
const int16_t order )
{
switch ( order )
{
case 1:
return IVAS_REND_AUDIO_CONFIG_FOA;
case 2:
return IVAS_REND_AUDIO_CONFIG_HOA2;
case 3:
return IVAS_REND_AUDIO_CONFIG_HOA3;
}
return IVAS_REND_AUDIO_CONFIG_UNKNOWN;
}
static bool parseInConfig(
const char *inFormatStr,
InputConfig *inConfig,
bool *sceneDescriptionInput )
{
char charBuf[FILENAME_MAX];
/* Initialize input config struct */
inConfig->numAudioObjects = 0;
inConfig->numAmbisonicsBuses = 0;
inConfig->numMultiChannelBuses = 0;
inConfig->numMasaBuses = 0;
/* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */
strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 );
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 IVAS_REND_AudioConfig enum. */
IVAS_REND_AudioConfig audioConfig = parseAudioConfig( inFormatStr );
switch ( audioConfig )
{
case IVAS_REND_AUDIO_CONFIG_MONO:
case IVAS_REND_AUDIO_CONFIG_STEREO:
case IVAS_REND_AUDIO_CONFIG_5_1:
case IVAS_REND_AUDIO_CONFIG_7_1:
case IVAS_REND_AUDIO_CONFIG_5_1_2:
case IVAS_REND_AUDIO_CONFIG_5_1_4:
case IVAS_REND_AUDIO_CONFIG_7_1_4:
inConfig->numMultiChannelBuses = 1;
inConfig->multiChannelBuses[0].audioConfig = audioConfig;
inConfig->multiChannelBuses[0].inputChannelIndex = 0;
inConfig->multiChannelBuses[0].gain_dB = 0.0f;
break;
case IVAS_REND_AUDIO_CONFIG_FOA:
case IVAS_REND_AUDIO_CONFIG_HOA2:
case IVAS_REND_AUDIO_CONFIG_HOA3:
inConfig->numAmbisonicsBuses = 1;
inConfig->ambisonicsBuses[0].audioConfig = audioConfig;
inConfig->ambisonicsBuses[0].inputChannelIndex = 0;
inConfig->ambisonicsBuses[0].gain_dB = 0.0f;
break;
case IVAS_REND_AUDIO_CONFIG_MASA1:
case IVAS_REND_AUDIO_CONFIG_MASA2:
inConfig->numMasaBuses = 1;
inConfig->masaBuses[0].audioConfig = audioConfig;
inConfig->masaBuses[0].inputChannelIndex = 0;
inConfig->masaBuses[0].gain_dB = 0.0f;
break;
case IVAS_REND_AUDIO_CONFIG_OBJECT:
/* If input format is objects, parse the characters after "ISM" to get number of objects */
{
char *ptr = NULL;
inConfig->numAudioObjects = (uint16_t) strtol( inFormatStr + 3, &ptr, 10 );
if ( ptr == NULL || *ptr != '\0' )
{
/* Failed to parse string as a number */
fprintf( stderr, "Cannot parse string \"%s\" as a valid input format", inFormatStr );
return false;
}
if ( inConfig->numAudioObjects > RENDERER_MAX_ISM_INPUTS )
{
fprintf( stderr, "Too many objects at input. Max %d supported.", RENDERER_MAX_ISM_INPUTS );
return false;
}
for ( int16_t i = 0; i < inConfig->numAudioObjects; ++i )
{
inConfig->audioObjects[i].audioConfig = audioConfig;
inConfig->audioObjects[i].inputChannelIndex = i;
inConfig->audioObjects[i].gain_dB = 0.0f;
}
}
break;
case IVAS_REND_AUDIO_CONFIG_UNKNOWN:
/* This case will be reached if parsing string to IVAS_REND_AudioConfig enum fails.
* Try to use the given string as a path to a custom loudspeaker layout file. */
{
ivas_error error = parseCustomLayoutFile( inFormatStr, &inConfig->inSetupCustom );
if ( error == IVAS_ERR_FAILED_FILE_OPEN )
{
/* Failed to open with given string - most likely wasn't a file path */
fprintf( stderr, "Unsupported input format: %s\n", inFormatStr );
return false;
}
if ( error != IVAS_ERR_OK )
{
fprintf( stderr, "Error while reading custom loudspeaker layout file %s\n", inFormatStr );
return false;
}
inConfig->numMultiChannelBuses = 1;
inConfig->multiChannelBuses[0].audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM;
inConfig->multiChannelBuses[0].inputChannelIndex = 0;
inConfig->multiChannelBuses[0].gain_dB = 0.0f;
}
break;
default:
/* Default case covers formats that are defined in the IVAS_REND_AudioConfig enum,
* but cannot be used at input, e.g. BINAURAL */
fprintf( stderr, "Unsupported input format: %s\n", inFormatStr );
return false;
}
return true;
}
static bool parseOutConfig(
const char *outputFormatStr,
OutputConfig *outConfig )
{
ivas_error error;
outConfig->audioConfig = parseAudioConfig( outputFormatStr );
/* If the string provided is not recognized as a valid output config,
* it's expected to be a path to a custom loudspeaker layout description file. */
if ( outConfig->audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN )
{
outConfig->audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM;
if ( ( error = parseCustomLayoutFile( outputFormatStr, &outConfig->outSetupCustom ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "Error while parsing output format option\n" );
return false;
}
}
return true;
}
static int8_t parseDiegeticPan(
char *value,
float *noDiegeticPan )
{
int8_t success;
success = 1;
to_upper( value );
if ( ( strcmp( value, "CENTER" ) == 0 ) || ( strchr( value, 'C' ) != NULL ) )
{
*noDiegeticPan = 0.f;
}
else if ( ( strcmp( value, "LEFT" ) == 0 ) || ( strchr( value, 'L' ) != NULL ) )
{
*noDiegeticPan = -1.f;
}
else if ( ( strcmp( value, "RIGHT" ) == 0 ) || ( strchr( value, 'R' ) != NULL ) )
{
*noDiegeticPan = 1.f;
}
else
{
*noDiegeticPan = (float) atof( value );
if ( *noDiegeticPan > 1.0f || *noDiegeticPan < -1.0f )
{
fprintf( stderr, "Error: Incorrect value for panning option argument specified!\n\n" );
success = 0;
}
}
return success ? 0 : -1;
}
static int8_t parseOrientationTracking(
char *value,
int8_t *tracking_type )
{
int8_t success;
success = 1;
to_upper( value );
if ( strcmp( value, "REF" ) == 0 )
{
*tracking_type = IVAS_ORIENT_TRK_REF;
}
else if ( strcmp( value, "AVG" ) == 0 )
{
*tracking_type = IVAS_ORIENT_TRK_AVG;
}
else
{
fprintf( stderr, "Error: Invalid orientation tracking type %s \n\n", value );
success = 0;
}
return success ? 0 : -1;
}
static IVAS_REND_AudioConfig parseAudioConfig(
const char *configString )
{
char charBuf[14];
charBuf[13] = '\0';
strncpy( charBuf, configString, sizeof( charBuf ) - 1 );
to_upper( charBuf );
if ( ( strcmp( charBuf, "MONO" ) == 0 ) || ( strcmp( charBuf, "HOA0" ) == 0 ) || ( strcmp( charBuf, "SBA0" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_MONO;
}
if ( ( strcmp( charBuf, "STEREO" ) == 0 ) || ( strcmp( charBuf, "CICP2" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_STEREO;
}
if ( ( strcmp( charBuf, "FOA" ) == 0 ) || ( strcmp( charBuf, "SBA1" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_FOA;
}
if ( ( strcmp( charBuf, "HOA2" ) == 0 ) || ( strcmp( charBuf, "SBA2" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_HOA2;
}
if ( ( strcmp( charBuf, "HOA3" ) == 0 ) || ( strcmp( charBuf, "SBA3" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_HOA3;
}
if ( ( strcmp( charBuf, "5_1" ) == 0 ) || ( strcmp( charBuf, "CICP6" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_5_1;
}
if ( ( strcmp( charBuf, "7_1" ) == 0 ) || ( strcmp( charBuf, "CICP12" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_7_1;
}
if ( ( strcmp( charBuf, "5_1_2" ) == 0 ) || ( strcmp( charBuf, "CICP14" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_5_1_2;
}
if ( ( strcmp( charBuf, "5_1_4" ) == 0 ) || ( strcmp( charBuf, "CICP16" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_5_1_4;
}
if ( ( strcmp( charBuf, "7_1_4" ) == 0 ) || ( strcmp( charBuf, "CICP19" ) == 0 ) )
{
return IVAS_REND_AUDIO_CONFIG_7_1_4;
}
if ( strncmp( charBuf, "ISM", 3 ) == 0 )
{
return IVAS_REND_AUDIO_CONFIG_OBJECT;
}
if ( strncmp( charBuf, "MASA", 4 ) == 0 )
{
switch ( charBuf[4] )
{
case '1':
return IVAS_REND_AUDIO_CONFIG_MASA1;
case '2':
return IVAS_REND_AUDIO_CONFIG_MASA2;
default:
return IVAS_REND_AUDIO_CONFIG_UNKNOWN;
}
}
if ( strcmp( charBuf, "BINAURAL_ROOM" ) == 0 )
{
return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM;
}
if ( strcmp( charBuf, "BINAURAL" ) == 0 )
{
return IVAS_REND_AUDIO_CONFIG_BINAURAL;
}
return IVAS_REND_AUDIO_CONFIG_UNKNOWN;
}
static 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 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.numAudioObjects != 0 ||
args.inConfig.numAmbisonicsBuses != 0 ||
args.inConfig.numMultiChannelBuses != 0 ||
args.inConfig.numMasaBuses != 0;
if ( !args.sceneDescriptionInput && !singleInputSpecified )
{
/* Neither scene description input nor single-type input was specified on command line */
tmpOption = findOptionById( CmdLnOptionId_inputFormat );
fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
missingRequiredArg = true;
}
if ( isEmptyString( args.outputFilePath ) )
{
tmpOption = findOptionById( CmdLnOptionId_outputFile );
fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
missingRequiredArg = true;
}
if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN )
{
tmpOption = findOptionById( CmdLnOptionId_outputFormat );
fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort );
missingRequiredArg = true;
}
if ( missingRequiredArg )
{
CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions );
}
return !missingRequiredArg;
}
static CmdlnArgs defaultArgs(
const char *executableName )
{
CmdlnArgs args;
strncpy( args.executableName, executableName, RENDERER_MAX_CLI_ARG_LENGTH );
clearString( args.inputFilePath );
clearString( args.outputFilePath );
args.sampleRate = 0;
args.inConfig.inSetupCustom.num_spk = 0;
args.inConfig.inSetupCustom.num_lfe = 0;
args.inConfig.numAudioObjects = 0;
args.inConfig.numAmbisonicsBuses = 0;
args.inConfig.numMultiChannelBuses = 0;
args.inConfig.numMasaBuses = 0;
args.outConfig.audioConfig = IVAS_REND_AUDIO_CONFIG_UNKNOWN;
args.outConfig.outSetupCustom.num_spk = 0;
args.outConfig.outSetupCustom.num_lfe = 0;
for ( int32_t i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i )
{
clearString( args.inMetadataFilePaths[i] );
}
args.numInMetadataFiles = 0;
clearString( args.headRotationFilePath );
clearString( args.customHrtfFilePath );
clearString( args.renderConfigFilePath );
args.orientationTracking = IVAS_ORIENT_TRK_REF;
args.noDiegeticPan = 0.0f;
args.delayCompensationEnabled = true;
args.quietModeEnabled = false;
args.sceneDescriptionInput = false;
args.inputGainGlobal = 1.0f;
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], RENDERER_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_ISM_INPUTS );
for ( int16_t i = 0; i < numOptionValues; ++i )
{
strncpy( args->inMetadataFilePaths[i], optionValues[i], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
}
args->numInMetadataFiles = numOptionValues;
break;
case CmdLnOptionId_outputFile:
assert( numOptionValues == 1 );
strncpy( args->outputFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
break;
case CmdLnOptionId_outputFormat:
assert( numOptionValues == 1 );
if ( !parseOutConfig( optionValues[0], &args->outConfig ) )
{
exit( -1 ); /* Error printout handled by failing function */
}
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], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
break;
case CmdLnOptionId_customHrtfFile:
assert( numOptionValues == 1 );
strncpy( args->customHrtfFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
break;
case CmdLnOptionId_renderConfigFile:
assert( numOptionValues == 1 );
strncpy( args->renderConfigFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 );
break;
case CmdLnOptionId_noDiegeticPan:
assert( numOptionValues == 1 );
if ( parseDiegeticPan( optionValues[0], &args->noDiegeticPan ) != 0 )
{
fprintf( stderr, "Unknown option for diegetic panning: %s\n", optionValues[0] );
exit( -1 );
}
break;
case CmdLnOptionId_orientationTracking:
assert( numOptionValues == 1 );
if ( parseOrientationTracking( optionValues[0], &args->orientationTracking ) != 0 )
{
fprintf( stderr, "Unknown option for orientation tracking: %s\n", optionValues[0] );
exit( -1 );
}
break;
case CmdLnOptionId_customLfeRouting:
assert( 0 && "Not yet implemented in CLI" );
break;
case CmdLnOptionId_noDelayCmp:
assert( numOptionValues == 0 );
args->delayCompensationEnabled = false;
break;
case CmdLnOptionId_quietModeEnabled:
assert( numOptionValues == 0 );
args->quietModeEnabled = true;
break;
case CmdLnOptionId_inputGain:
assert( numOptionValues == 1 );
args->inputGainGlobal = strtof( optionValues[0], NULL );
if ( args->inputGainGlobal == 0.0f )
{
fprintf( stderr, "Invalid input gain specified\n" );
exit( -1 );
}
break;
default:
assert( 0 && "This should be unreachable - all command line options should be explicitly handled." );
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;
}
IsmPositionProvider *IsmPositionProvider_open(
void )
{
IsmPositionProvider *ipp;
uint16_t i;
ipp = (IsmPositionProvider *) count_malloc( sizeof( IsmPositionProvider ) );
ipp->frameCounter = 0;
ipp->numObjects = 0;
for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i )
{
ipp->ismReaders[i] = NULL;
ipp->positions[i] = NULL;
ipp->positionDurations[i] = NULL;
ipp->currentPositionIdxs[i] = 0;
ipp->durationCounters[i] = 0;
}
return ipp;
}
void getMetadataFromFileReader(
IsmFileReader *ismReader,
ObjectPositionBuffer *objectMetadataBuffer,
const uint32_t objIdx )
{
IVAS_ISM_METADATA ismMetadata;
ivas_error error;
if ( ( error = IsmFileReader_readNextFrame( ismReader, &ismMetadata ) ) != IVAS_ERR_OK )
{
fprintf( stderr, "\nError (%s) while reading ism metadata from: %s\n\n", ivas_error_to_string( error ), IsmFileReader_getFilePath( ismReader ) );
exit( -1 );
}
objectMetadataBuffer->positions[objIdx].azimuth = ismMetadata.azimuth;
objectMetadataBuffer->positions[objIdx].elevation = ismMetadata.elevation;
return;
}
void readFromShorthandMetadata(
IsmPositionProvider *positionProvider,
ObjectPositionBuffer *objectMetadataBuffer,
const uint32_t objIdx )
{
uint32_t preUpdatePositionIdx;
uint32_t postUpdatePositionIdx;
preUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx];
if ( positionProvider->durationCounters[objIdx] == positionProvider->positionDurations[objIdx][preUpdatePositionIdx] )
{
positionProvider->durationCounters[objIdx] = 0;
positionProvider->currentPositionIdxs[objIdx] = ( positionProvider->currentPositionIdxs[objIdx] + 1 ) % positionProvider->numPositions[objIdx];
}
++positionProvider->durationCounters[objIdx];
postUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx];
objectMetadataBuffer->positions[objIdx] = positionProvider->positions[objIdx][postUpdatePositionIdx];
return;
}
void IsmPositionProvider_getNextFrame(
IsmPositionProvider *positionProvider,
ObjectPositionBuffer *objectMetadataBuffer )
{
uint32_t objIdx;
objectMetadataBuffer->numObjects = positionProvider->numObjects;
for ( objIdx = 0; objIdx < positionProvider->numObjects; ++objIdx )
{
if ( positionProvider->ismReaders[objIdx] != NULL )
{
getMetadataFromFileReader( positionProvider->ismReaders[objIdx], objectMetadataBuffer, objIdx );
}
else
{
readFromShorthandMetadata( positionProvider, objectMetadataBuffer, objIdx );
}
/* Wrap azimuth to lie within (-180, 180] range */
while ( objectMetadataBuffer->positions[objIdx].azimuth < 0.0f )
{
objectMetadataBuffer->positions[objIdx].azimuth += 360.0f;
}
while ( objectMetadataBuffer->positions[objIdx].azimuth >= 360.0f )
{
objectMetadataBuffer->positions[objIdx].azimuth -= 360.0f;
}
/* Clamp elevation to lie within [-90, 90] range (can't be wrapped easily) */
objectMetadataBuffer->positions[objIdx].elevation = min( max( objectMetadataBuffer->positions[objIdx].elevation, -90 ), 90 );
}
++positionProvider->frameCounter;
return;
}
void IsmPositionProvider_close( IsmPositionProvider *positionProvider )
{
uint32_t i;
if ( positionProvider == NULL )
{
assert( !"Can't close IsmPositionProvider - pointer is NULL" );
}
for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i )
{
if ( positionProvider->ismReaders[i] != NULL )
{
IsmFileReader_close( &positionProvider->ismReaders[i] );
}
if ( positionProvider->positions[i] != NULL )
{
count_free( positionProvider->positions[i] );
}
if ( positionProvider->positionDurations[i] != NULL )
{
count_free( positionProvider->positionDurations[i] );
}
}
count_free( positionProvider );
return;
}
static void splitConfigFile(
const char *mdfFilePath,
char *metadataString,
uint32_t *metadataStringLength,
char *wavFileName,
uint32_t *wavFileNameLength )
{
FILE *file;
uint32_t bufferlength;
char wavLine[FILENAME_MAX];
uint32_t currentPositionIdxs;
uint32_t mdlength;
memset( metadataString, 0, *metadataStringLength );
memset( wavFileName, 0, (int16_t) *wavFileNameLength );
file = fopen( mdfFilePath, "rb" );
if ( !file )
{
fprintf( stderr, "Couldn't open metadata file %s\n", mdfFilePath );
exit( -1 );
}
fseek( file, 0, SEEK_END );
bufferlength = ftell( file );
fseek( file, 0, SEEK_SET );
if ( fgets( wavLine, (int) *wavFileNameLength, file ) == NULL )
{
fprintf( stderr, "Error reading metadata\n" );
exit( -1 );
}
currentPositionIdxs = ftell( file );
if ( *wavFileNameLength < currentPositionIdxs )
{
assert( !"Couldn't read wavFileName, string buffer too small" );
}
if ( !sscanf( wavLine, "%s", wavFileName ) )
{
fprintf( stderr, "Error reading metadata\n" );
exit( -1 );
}
*wavFileNameLength = (uint32_t) strlen( wavFileName );
mdlength = bufferlength - currentPositionIdxs;
/* "+1" for null termination */
if ( *metadataStringLength + 1 < mdlength )
{
assert( !"Couldn't read metadata string, string buffer too small" );
}
fread( metadataString, 1, mdlength, file );
metadataString[mdlength] = '\0';
*metadataStringLength = mdlength + 1;
fclose( file );
return;
}
/* r: pointer to character following last found delimiter */
static char *readNextMetadataChunkFrom(
char *start_char,
char *line,
const char *delimiter )
{
char *token;
/* start_char can be NULL - it's used to continue parsing with strtok */
assert( line != NULL && delimiter != NULL && "unexpected NULL ptr given to readNextMetadataChunkFrom()" );
token = strtok( start_char, delimiter );
/* End of string reached */
if ( token == NULL )
{
/* Clear `line` from previous contents and return NULL */
clearString( line );
return NULL;
}
strcpy( line, token );
return token + strlen( token ) + 1;
}
/* r: pointer to character following last found delimiter */
static char *readNextMetadataChunk(
char *line,
const char *delimiter )
{
return readNextMetadataChunkFrom( NULL, line, delimiter );
}
static void parseUint8(
const char *line,
uint8_t *ret )
{
char *ptr;
ptr = NULL;
*ret = (uint8_t) strtol( line, &ptr, 10 );
if ( ptr == NULL || *ptr != '\0' )
{
fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line );
exit( -1 );
}
return;
}
static int8_t parseUint32(
const char *line,
uint32_t *ret )
{
char *ptr;
ptr = NULL;
*ret = strtol( line, &ptr, 10 );
if ( ptr == NULL || *ptr != '\0' )
{
return -1;
}
return 0;
}
static int8_t parseInt32(
const char *line,
int32_t *ret )
{
char *ptr;
ptr = NULL;
*ret = strtol( line, &ptr, 10 );
if ( ptr == NULL || *ptr != '\0' )
{
return -1;
}
return 0;
}
static void parseOptionalInputValues(
char *line,
float *gain_dB )
{
char *parse_pos;
char *key;
char *value;
char *endptr;
endptr = NULL;
/* Set default values, in case some values are not specified */
*gain_dB = 0.f;
/* Save parsing position - will have to be passed to strtok to resume parsing after using strtok with non-NULL value below */
parse_pos = readNextMetadataChunk( line, "\n" );
/* Look for optional metadata until end of string or next input identifier is found */
while ( parse_pos != NULL && strcmp( line, "MC" ) != 0 && strcmp( line, "SBA" ) != 0 && strcmp( line, "ISM" ) != 0 && strcmp( line, "MASA" ) != 0 )
{
key = strtok( line, ":" );
value = strtok( NULL, "\n" );
if ( strcmp( key, "gain_dB" ) == 0 )
{
*gain_dB = (float) strtod( value, &endptr );
if ( *endptr != '\0' )
{
fprintf( stderr, "Cannot parse string string \"%s\" as a float value\n", value );
exit( -1 );
}
}
else
{
fprintf( stderr, "Unsupported optional key: %s\n", key );
exit( -1 );
}
parse_pos = readNextMetadataChunkFrom( parse_pos, line, "\n" );
}
return;
}
static void parseObjectPosition(
char *line,
IVAS_REND_AudioObjectPosition *position,
uint16_t *positionDuration )
{
char *endptr;
readNextMetadataChunk( line, "," );
*positionDuration = (uint16_t) strtol( line, &endptr, 10 );
if ( *endptr != '\0' )
{
fprintf( stderr, "Error reading metadata\n" );
exit( -1 );
}
readNextMetadataChunk( line, "," );
position->azimuth = strtof( line, &endptr );
if ( *endptr != '\0' )
{
fprintf( stderr, "Error reading metadata\n" );
exit( -1 );
}
readNextMetadataChunk( line, "\n" );
position->elevation = strtof( line, &endptr );
if ( *endptr != '\0' )
{
fprintf( stderr, "Error reading metadata\n" );
exit( -1 );
}
return;
}
static void parseIsm(
char *line,
char *inDir,
InputConfig *inConfig,
IsmPositionProvider *positionProvider,
const int32_t idx )
{
uint32_t numberOfObjectPositionsToRead;
uint32_t i;
readNextMetadataChunk( line, "\n" );
parseInt32( line, &inConfig->audioObjects[idx].inputChannelIndex );
--inConfig->audioObjects[idx].inputChannelIndex; /* Convert from 1-indexing */
readNextMetadataChunk( line, "\n" );
/* Try to interpret line as number of positions to read */
if ( parseUint32( line, &numberOfObjectPositionsToRead ) == 0 )
{
positionProvider->numPositions[idx] = numberOfObjectPositionsToRead;
positionProvider->positions[idx] = count_malloc( numberOfObjectPositionsToRead * sizeof( IVAS_REND_AudioObjectPosition ) );
positionProvider->positionDurations[idx] = count_malloc( numberOfObjectPositionsToRead * sizeof( uint16_t ) );
for ( i = 0; i < numberOfObjectPositionsToRead; ++i )
{
parseObjectPosition( line, &positionProvider->positions[idx][i], &positionProvider->positionDurations[idx][i] );
}
}
else /* If not a number, it is a relative path from main metadata file to a metadata file */
{
char fullpath[FILENAME_MAX];
fullpath[0] = '\0';
strncat( fullpath, inDir, strlen( inDir ) );
strncat( fullpath, line, sizeof( fullpath ) - strlen( fullpath ) - 1 );
if ( ( positionProvider->ismReaders[idx] = IsmFileReader_open( fullpath ) ) == NULL )
{
fprintf( stderr, "Error: ISM input metadata file %s could not be opened\n", fullpath );
exit( -1 );
}
}
/* Read optional values */
parseOptionalInputValues( line, &inConfig->audioObjects[idx].gain_dB );
return;
}
static void parseSba(
char *line,
InputConfig *inConfig,
const int32_t idx )
{
uint8_t ambiOrder;
readNextMetadataChunk( line, "\n" );
parseInt32( line, &inConfig->ambisonicsBuses[idx].inputChannelIndex );
--inConfig->ambisonicsBuses[idx].inputChannelIndex; /* Convert from 1-indexing */
readNextMetadataChunk( line, "\n" );
parseUint8( line, &ambiOrder );
inConfig->ambisonicsBuses[idx].audioConfig = ambisonicsOrderToEnum( ambiOrder );
/* Read optional values */
parseOptionalInputValues( line, &inConfig->ambisonicsBuses[idx].gain_dB );
return;
}
static void parseMc(
char *line,
InputConfig *inConfig,
const int32_t idx )
{
readNextMetadataChunk( line, "\n" );
parseInt32( line, &inConfig->multiChannelBuses[idx].inputChannelIndex );
--inConfig->multiChannelBuses[idx].inputChannelIndex; /* Convert from 1-indexing */
readNextMetadataChunk( line, "\n" );
IVAS_REND_AudioConfig cfg = parseAudioConfig( line );
if ( cfg == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM )
{
parseCustomLayoutFile( line, &inConfig->inSetupCustom );
}
else
{
inConfig->multiChannelBuses[idx].audioConfig = cfg;
}
/* Read optional values */
parseOptionalInputValues( line, &inConfig->multiChannelBuses[idx].gain_dB );
return;
}
static void parseMasa(
char *line,
char *inDir,
InputConfig *inConfig,
MasaFileReader **masaReaders,
const int32_t idx )
{
readNextMetadataChunk( line, "\n" );
parseInt32( line, &inConfig->masaBuses[idx].inputChannelIndex );
--inConfig->masaBuses[idx].inputChannelIndex; /* Convert from 1-indexing */
readNextMetadataChunk( line, "\n" );
/* Allow both just the number of TCs or MASAx. parseStrToAudioCfg() only accepts MASAx, so prepend if necessary. */
if ( strncmp( line, "MASA", 4 ) != 0 )
{
char numTcs = *line;
sprintf( line, "MASA%c", numTcs );
}
inConfig->masaBuses[idx].audioConfig = parseAudioConfig( line );
readNextMetadataChunk( line, "\n" );
char fullpath[FILENAME_MAX];
fullpath[0] = '\0';
strncat( fullpath, inDir, strlen( inDir ) );
strncat( fullpath, line, sizeof( fullpath ) - strlen( fullpath ) - 1 );
if ( ( masaReaders[idx] = MasaFileReader_open( fullpath ) ) == NULL )
{
fprintf( stderr, "Error: MASA metadata file %s could not be opened\n", fullpath );
exit( -1 );
}
/* Read optional values */
parseOptionalInputValues( line, &inConfig->masaBuses[idx].gain_dB );
return;
}
static ivas_error parseCustomLayoutFile(
const char *filePath,
IVAS_CUSTOM_LS_DATA *pLsSetupCustom )
{
LsCustomFileReader *hLsCustomReader = NULL;
IVAS_CUSTOM_LS_DATA hLsCustomData;
ivas_error error;
if ( ( error = CustomLsReader_open( filePath, &hLsCustomReader ) ) != IVAS_ERR_OK )
{
return error;
}
if ( CustomLsFileReading( hLsCustomReader, &hLsCustomData ) != LS_CUSTOM_FILEREADER_NO_ERROR )
{
return error;
}
pLsSetupCustom->num_spk = hLsCustomData.num_spk;
mvr2r( hLsCustomData.azimuth, pLsSetupCustom->azimuth, hLsCustomData.num_spk );
mvr2r( hLsCustomData.elevation, pLsSetupCustom->elevation, hLsCustomData.num_spk );
/* Loudspeaker LFE */
pLsSetupCustom->num_lfe = hLsCustomData.num_lfe;
mvs2s( hLsCustomData.lfe_idx, pLsSetupCustom->lfe_idx, hLsCustomData.num_lfe );
CustomLsReader_close( &hLsCustomReader );
return IVAS_ERR_OK;
}
static void parseMetadata(
char *metadataString,
char *inDir,
InputConfig *inConfig,
IsmPositionProvider *positionProvider,
MasaFileReader **masaReaders )
{
char line[RENDERER_MAX_METADATA_LINE_LENGTH];
char *delimiter;
char *token;
uint8_t totalNumberOfAudioObjects;
uint8_t counterChannelAudioObjects;
uint8_t counterAmbisonicsAudioObjects;
uint8_t counterMonoAudioObjects;
uint8_t counterMasaInputs;
uint8_t num_parsed_inputs;
delimiter = "\n";
token = strtok( metadataString, delimiter );
if ( token == NULL )
{
fprintf( stderr, "Unexpected metadata format\n" );
exit( -1 );
}
if ( !sscanf( token, "%s", line ) )
{
fprintf( stderr, "Unexpected metadata format\n" );
exit( -1 );
}
parseUint8( line, &totalNumberOfAudioObjects );
if ( totalNumberOfAudioObjects <= 0 )
{
fprintf( stderr, "Invalid metadata: number of inputs should be > 0\n" );
exit( -1 );
}
num_parsed_inputs = 0;
counterChannelAudioObjects = 0;
counterAmbisonicsAudioObjects = 0;
counterMonoAudioObjects = 0;
counterMasaInputs = 0;
readNextMetadataChunk( line, delimiter );
while ( num_parsed_inputs < totalNumberOfAudioObjects )
{
/* `line` will already contain the identifier ("MC", "SBA" or "ISM") after previous iteration */
if ( strcmp( line, "MC" ) == 0 )
{
++counterChannelAudioObjects;
if ( counterChannelAudioObjects > RENDERER_MAX_MC_INPUTS )
{
fprintf( stderr, "Metadata exceeds the supported number of MC inputs\n" );
exit( -1 );
}
parseMc( line, inConfig, counterChannelAudioObjects - 1 );
}
else if ( strcmp( line, "SBA" ) == 0 )
{
++counterAmbisonicsAudioObjects;
if ( counterAmbisonicsAudioObjects > RENDERER_MAX_SBA_INPUTS )
{
fprintf( stderr, "Metadata exceeds the supported number of SBA inputs\n" );
exit( -1 );
}
parseSba( line, inConfig, counterAmbisonicsAudioObjects - 1 );
}
else if ( strcmp( line, "ISM" ) == 0 )
{
++counterMonoAudioObjects;
if ( counterMonoAudioObjects > RENDERER_MAX_ISM_INPUTS )
{
fprintf( stderr, "Metadata exceeds the supported number of ISM inputs\n" );
exit( -1 );
}
parseIsm( line, inDir, inConfig, positionProvider, counterMonoAudioObjects - 1 );
}
else if ( strcmp( line, "MASA" ) == 0 )
{
++counterMasaInputs;
if ( counterMasaInputs > RENDERER_MAX_MASA_INPUTS )
{
fprintf( stderr, "Metadata exceeds the supported number of MASA inputs\n" );
exit( -1 );
}
parseMasa( line, inDir, inConfig, masaReaders, counterMasaInputs - 1 );
}
else if ( isEmptyString( line ) )
{
fprintf( stderr, "Metadata string too short - expected %d inputs, found %d.\n", totalNumberOfAudioObjects, num_parsed_inputs );
exit( -1 );
}
else
{
fprintf( stderr, "Unexpected metadata identifier\n" );
exit( -1 );
}
++num_parsed_inputs;
}
inConfig->numAudioObjects = counterMonoAudioObjects;
inConfig->numAmbisonicsBuses = counterAmbisonicsAudioObjects;
inConfig->numMultiChannelBuses = counterChannelAudioObjects;
inConfig->numMasaBuses = counterMasaInputs;
positionProvider->numObjects = counterMonoAudioObjects;
/* check for trailing text */
token = strtok( NULL, delimiter );
if ( token != NULL && sscanf( token, "%s", line ) )
{
fprintf( stderr, "Trailing text in metadata file\n" );
exit( -1 );
}
return;
}
static void parseSceneDescriptionFile(
char *path,
char *audioFilePath,
InputConfig *inConfig,
IsmPositionProvider *positionProvider,
MasaFileReader **masaReaders )
{
uint32_t inAudioFilePathLen;
char inAudioFilePath[FILENAME_MAX];
uint32_t mtdStrLen;
char mtdStr[RENDERER_MAX_METADATA_LENGTH];
char inDir[FILENAME_MAX];
char *lastSlash = NULL;
inAudioFilePathLen = FILENAME_MAX;
mtdStrLen = RENDERER_MAX_METADATA_LENGTH;
splitConfigFile( path, mtdStr, &mtdStrLen, inAudioFilePath, &inAudioFilePathLen );
remove_cr( mtdStr );
convert_backslash( inAudioFilePath );
/* Trim config file path to get path to the dir containing it */
lastSlash = strrchr( path, SEP_FOLDER );
inDir[0] = '\0';
if ( lastSlash != NULL )
{
strncat( inDir, path, ( lastSlash - path + 1 ) );
}
/* Append audio file path (relative to config file location)
* to config file location path to get full absolute path */
strcpy( audioFilePath, inDir );
strncat( audioFilePath, inAudioFilePath, inAudioFilePathLen );
parseMetadata( mtdStr, inDir, inConfig, positionProvider, masaReaders );
}
static void printSupportedAudioConfigs()
{
uint16_t i;
const char *supportedFormats[] = {
"MONO",
"STEREO",
"5_1",
"5_1_2",
"5_1_4",
"7_1",
"7_1_4",
"Path to Custom Loudspeaker .txt file",
"FOA",
"HOA2",
"HOA3",
"ISMx (input only)",
"MASAx (input only)",
"BINAURAL (output only)",
"BINAURAL_ROOM (output only)",
};
fprintf( stdout, "Supported audio formats:\n" );
for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ )
{
fprintf( stdout, "%s\n", supportedFormats[i] );
}
return;
}
// VE2AT: possibly move these functions to cmdln_parser.c ?
static void convert_backslash(
char *str )
{
int16_t i, len;
/* check that all backslashes are correct on the given platform */
len = (int16_t) strlen( str );
for ( i = 0; i < len; i++ )
{
#ifdef _WIN32
if ( str[i] == '/' )
{
str[i] = '\\';
}
#else
if ( str[i] == '\\' )
{
str[i] = '/';
}
#endif
}
return;
}
static void remove_cr( char *str )
{
char *pos;
/* remove all \r characters from the string */
pos = strchr( str, '\r' );
while ( pos != NULL )
{
strcpy( pos, pos + 1 );
pos = strchr( pos, '\r' );
}
return;
}
static void clearString(
char *str )
{
str[0] = '\0';
return;
}
static bool isEmptyString(
const char *str )
{
return str[0] == '\0';
}
/*--------------------------------------------------------------------------*
* 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;
i = 0;
for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl )
{
for ( chnl = 0; chnl < numChannels; ++chnl )
{
intBuffer[i] = (int16_t) roundf( floatBuffer[chnl * numSamplesPerChannel + smpl] );
++i;
}
}
return;
}
#else
int main(
int argc,
char **argv )
{
(void) argc;
(void) argv;
fprintf( stderr, "Enable EXT_RENDERER in options.h to use the external renderer.\n" );
return 0;
}
#endif
......@@ -9,8 +9,6 @@ fi
make clean && make all -j
# build unittests
make unittests -j
# build prerenderer
make -C scripts/prerenderer -j
# build standalone TD object renderer
make -C scripts/td_object_renderer/object_renderer_standalone -j
import re
import os
FILE_PATH = os.path.join(os.path.dirname(__file__), "..", "lib_com", "options.h")
RE_TO_COMMENT_OUT = re.compile(r"#define\s+RAM_COUNTING_TOOL")
def main():
with open(FILE_PATH, "r", encoding="utf-8") as file:
lines = file.readlines()
for i, line in enumerate(lines):
lines[i] = RE_TO_COMMENT_OUT.sub(lambda x: f"/* {x.group(0)} */", line)
with open(FILE_PATH, "w", encoding="utf-8") as file:
file.writelines(lines)
if __name__ == "__main__":
main()
......@@ -7,7 +7,7 @@ import pathlib
DURATION = "120"
CFG = "ci_linux.json"
CFG = "ci_linux_ltv.json"
SUPPORTED_TESTS = ["CLANG1", "CLANG2", "CLANG3", "VALGRIND"]
EP_FILE = "ep_015.g192"
GENPATT_CMD = f"gen-patt -tailstat -fer -g192 -gamma 0 -rate 0.15 -tol 0.001 -reset -n {int(DURATION) * 50} {EP_FILE}"
......@@ -32,16 +32,24 @@ def main(args):
def get_modes(in_format: str) -> list:
cmd = [SCRIPT_DIR.joinpath("runIvasCodec.py"), "-l"]
cmd = [
SCRIPT_DIR.joinpath("runIvasCodec.py"),
"-C",
"MC" if in_format in MC_MODES else in_format,
"-l"
]
list_process = subprocess.run(cmd, capture_output=True)
output = list_process.stdout.decode("utf8")
mode_list = output.splitlines()
# correction for multichannel modes to avoid selecting some mono modes...
if in_format in MC_MODES:
in_format = "MC_" + in_format
in_format = "MC_" + in_format + "_b"
mode_list = [m for m in mode_list if in_format in m]
return [m for m in output.splitlines() if in_format in m]
return mode_list
def run_check(modes: list, out_formats: list, tests: list, run_fec: bool = True):
......@@ -82,12 +90,20 @@ def run_check(modes: list, out_formats: list, tests: list, run_fec: bool = True)
subprocess.call(GENPATT_CMD.split())
# cleanup to avoid script errors
# we want "logs" and "dec" subfolders to be empty -> delete and recreate them
cleanup_folders = ["logs", "dec"]
# we want "logs" and "dec" subfolders to be empty -> delete "dec" and rename "log"
# to keep the log files from the first run with no frame losses
folders_to_delete = ["dec"]
folders_to_backup = ["logs"]
for t in tests:
for fol in cleanup_folders:
for fol in folders_to_delete:
for fi in pathlib.Path(t).joinpath(fol).iterdir():
fi.unlink()
for fol in folders_to_backup:
path = pathlib.Path(t).joinpath(fol)
new_name = pathlib.Path(str(path) + "_noPLC")
path.rename(new_name)
# need empty log folder to avoid crashes
path.mkdir()
cmd_fec = cmd_no_fec + ["--decoder_only", "-f", EP_FILE]
print("======== Script command line WITH plc: ========\n{}".format(" ".join(cmd_no_fec)))
......