diff --git a/.gitignore b/.gitignore index 2024f865f12beaeeb9f2e46dfaa14a5ae851c790..bceaf41a73abf285da9abdc484f2e55401c648dd 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,10 @@ binary/ tests/**/[c|d]ut tests/**/ref tests/*/testv +tests/hrtf_binary_loading/bitstream/* +tests/hrtf_binary_loading/dec_out_*/* scripts/testv/*_cut*.pcm +scripts/testv/*_cut*.wav scripts/testv/stvOMASA_*.met scripts/testv/stvOMASA_*.csv scripts/testv/stvOMASA_2ISM_1MASA1TC48c.wav diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f3dd07fca2c9dbe34b779908afad4f0d05de93b1..3a0bf48e45f8b9228173b25dc39c2179b0bf545a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,6 +20,11 @@ variables: - 'default' - 'test-be-release' - 'test-long-self-test' + - 'ivas-conformance' + - 'ivas-conformance-linux' + GIT_CLEAN_FLAGS: -ffdxq + TESTCASE_TIMEOUT_STV_SANITIZERS: 180 + TESTCASE_TIMEOUT_LTV_SANITIZERS: 1200 default: @@ -50,7 +55,14 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'test-long-self-test' variables: IVAS_PIPELINE_NAME: 'Test long self-test against main pipeline: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'ivas-conformance' + variables: + IVAS_PIPELINE_NAME: 'Draft IVAS Conformance test: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'trigger' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + variables: + IVAS_PIPELINE_NAME: 'Draft IVAS Conformance test -- Linux: $CI_COMMIT_BRANCH' + stages: - .pre @@ -160,6 +172,10 @@ stages: - sed -i.bak -e "s/\/\*[[:space:]]*\(#define[[:space:]]*SPLIT_REND_WITH_HEAD_ROT\)[[:space:]]*\*\//\1/g" ./lib_com/options.h - sed -i.bak -e "s/\/\/[[:space:]]*\(#define[[:space:]]*SPLIT_REND_WITH_HEAD_ROT\)/\1/g" ./lib_com/options.h +.disable-limiter: &disable-limiter +# automatically enable #define DISABLE_LIMITER in options.h, handling both /**/-comment and //-comment + - sed -i.bak -e "s/\/\*[[:space:]]*\(#define[[:space:]]*DISABLE_LIMITER\)[[:space:]]*\*\//\1/g" ./lib_com/options.h + .get-commits-behind-count: &get-commits-behind-count - echo $CI_COMMIT_SHA - echo $CI_MERGE_REQUEST_TARGET_BRANCH_NAME @@ -181,6 +197,34 @@ stages: - (Get-Content -Path "CMakeLists.txt") -replace '# \(add_compile_options\("\/WX"\)\)', '$1' | Set-Content -Path "CMakeLists.txt" - Get-ChildItem -Path "Workspace_msvc" -Filter "*.vcxproj" | ForEach-Object { (Get-Content -Path $_.FullName) -replace 'false', 'true' | Set-Content -Path $_.FullName } +# to be reused in MR and LTV-scheduled sanitizer test jobs +# set CLANG_NUM, SELFTEST_SANITY_TIMEOUT and SELF_TEST_PRM_FILE in before_script section +.sanitizer-selftest-anchor: &sanitizer-selftest-anchor + script: + - *print-common-info + - *copy-ltv-files-to-testv-dir + - make clean + - make -j CLANG=$CLANG_NUM + - testcase_timeout=$SELFTEST_SANITY_TIMEOUT + - export UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1 + + - exit_code20=0 + - exit_code10=0 + - exit_code5=0 + + - if [ $CLANG_NUM -eq 1 ]; then sanitizer_type="MemorySanitizer"; elif [ $CLANG_NUM -eq 2 ]; then sanitizer_type="AddressSanitizer"; elif [ $CLANG_NUM -eq 3 ]; then sanitizer_type="UndefinedBehaviorSanitizer"; else echo "Wrong CLANG_NUM $CLANG_NUM given!"; exit 1; fi + + # run encoder and decoder with 20ms renderer framesize first, use reference creation mode + - python3 -m pytest $SELF_TEST_PRM_FILE -v --update_ref 1 -m create_ref --html=report-20ms.html --self-contained-html --junit-xml=report-junit-20ms.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code20=$? + # for 10ms and 5ms renderer framesize, we only need to run the decoder part as renderer framesize is a decoder-only option + # set tolerance very high do ignore any BE differences due to the different renderer framesizes, those can appear due to the limiter being active + # we are only interested in runtime errors from the sanitizers and ignore the diffs + - python3 -m pytest $SELF_TEST_PRM_FILE -v --html=report-5ms.html --self-contained-html --junit-xml=report-junit-5ms.xml --dut_fr 5 --decoder_only --abs_tol 100000 || exit_code5=$? + - python3 -m pytest $SELF_TEST_PRM_FILE -v --html=report-10ms.html --self-contained-html --junit-xml=report-junit-10ms.xml --dut_fr 10 --decoder_only --abs_tol 100000 || exit_code10=$? + + - if [ $exit_code20 -ne 0 ] || [ $exit_code10 -ne 0 ] || [ $exit_code5 -ne 0 ]; then exit 1; fi + + # --------------------------------------------------------------- # Job templates # --------------------------------------------------------------- @@ -202,6 +246,10 @@ stages: when: never - if: $MANUAL_PIPELINE_TYPE == 'test-long-self-test' # Skip all the normal jobs when testing manually against release codec when: never + - if: $MANUAL_PIPELINE_TYPE == 'ivas-conformance' + when: never + - if: $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + when: never - when: on_success .rules-merge-request: @@ -248,6 +296,51 @@ stages: - python3 scripts/prepare_combined_format_inputs.py - cp -r scripts/testv/* $TESTV_DIR/ +.sanitizer-selftest-on-mr: + stage: test + extends: + - .test-job-linux-needs-testv-dir + - .rules-merge-request + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + expire_in: 1 week + when: always + paths: + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml + - report-20ms.html + - report-10ms.html + - report-5ms.html + expose_as: "Sanitizer selftest results" + reports: + junit: + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml + +.sanitizer-selftest-ltv: + stage: test + extends: + - .test-job-linux-needs-testv-dir + artifacts: + name: "$CI_JOB_NAME--sha-$CI_COMMIT_SHORT_SHA--results" + expire_in: 2 week + when: always + paths: + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml + - report-20ms.html + - report-10ms.html + - report-5ms.html + expose_as: "Sanitizer selftest results" + reports: + junit: + - report-junit-20ms.xml + - report-junit-10ms.xml + - report-junit-5ms.xml + # --------------------------------------------------------------- # .pre jobs for setting up things # --------------------------------------------------------------- @@ -398,7 +491,7 @@ build-codec-windows-msbuild: script: - *print-common-info-windows - *activate-WX-windows - - py .\scripts\strip_split_rendering.py + - python .\scripts\strip_split_rendering.py - MSBuild.exe -maxcpucount .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug # --------------------------------------------------------------- @@ -442,83 +535,84 @@ codec-smoke-test: # code selftest testvectors with memory-sanitizer binaries codec-msan: extends: - - .test-job-linux-needs-testv-dir - - .rules-merge-request - stage: test - needs: ["build-codec-sanitizers-linux"] - script: - - *print-common-info - - make clean - - make -j CLANG=1 - - testcase_timeout=180 - - exit_code=0 - - python3 -m pytest tests/codec_be_on_mr_nonselection/test_param_file.py -v --update_ref 1 -m create_ref --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code=$? - - if [ $exit_code != 0 ] ; then echo "Run errors found by Clang memory-sanitizer"; exit 1; fi - artifacts: - name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" - expire_in: 1 week - when: always - paths: - - report-junit.xml - - report.html - expose_as: "msan selftest results" - reports: - junit: - - report-junit.xml + - .sanitizer-selftest-on-mr + tags: + - ivas-linux-fast + before_script: + - CLANG_NUM=1 + - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS + - SELF_TEST_PRM_FILE="tests/codec_be_on_mr_nonselection/test_param_file.py" + <<: *sanitizer-selftest-anchor # code selftest testvectors with address-sanitizer binaries codec-asan: extends: - - .test-job-linux-needs-testv-dir - - .rules-merge-request - stage: test - needs: ["build-codec-sanitizers-linux"] - script: - - *print-common-info - - make clean - - make -j CLANG=2 - - testcase_timeout=180 - - exit_code=0 - - python3 -m pytest tests/codec_be_on_mr_nonselection/test_param_file.py -v --update_ref 1 -m create_ref --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code=$? - - if [ $exit_code != 0 ] ; then echo "Run errors found by Clang address-sanitizer"; exit 1; fi - artifacts: - name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" - expire_in: 1 week - when: always - paths: - - report-junit.xml - - report.html - expose_as: "asan selftest results" - reports: - junit: - - report-junit.xml + - .sanitizer-selftest-on-mr + before_script: + - CLANG_NUM=2 + - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS + - SELF_TEST_PRM_FILE="tests/codec_be_on_mr_nonselection/test_param_file.py" + <<: *sanitizer-selftest-anchor -# code selftest testvectors with address-sanitizer binaries +# code selftest testvectors with undefined-behaviour-sanitizer binaries codec-usan: extends: - - .test-job-linux-needs-testv-dir + - .sanitizer-selftest-on-mr + before_script: + - CLANG_NUM=3 + - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_STV_SANITIZERS + - SELF_TEST_PRM_FILE="tests/codec_be_on_mr_nonselection/test_param_file.py" + <<: *sanitizer-selftest-anchor + +# compare bit-exactness between 5ms and 20 on the branch +pytest-compare-20ms-and-5ms-rendering: + extends: + - .test-job-linux - .rules-merge-request stage: test - needs: ["build-codec-sanitizers-linux"] + needs: ["build-codec-linux-cmake", "build-codec-linux-make", "build-codec-instrumented-linux", "build-codec-sanitizers-linux"] script: - *print-common-info + - *disable-limiter - make clean - - make -j CLANG=3 - - testcase_timeout=180 + - make -j + ### prepare pytest + - cp IVAS_cod IVAS_cod_ref + - cp IVAS_dec IVAS_dec_ref + # create short test vectors + - python3 tests/create_short_testvectors.py + # create references + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 -m create_ref + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 -m create_ref_part2 + ### run pytest - exit_code=0 - - UBSAN_OPTIONS=suppressions=scripts/ubsan.supp,report_error_type=1 python3 -m pytest tests/codec_be_on_mr_nonselection/test_param_file.py -v --update_ref 1 -m create_ref --html=report.html --self-contained-html --junit-xml=report-junit.xml --testcase_timeout=$testcase_timeout --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec || exit_code=$? - - if [ $exit_code != 0 ] ; then echo "Run errors found by Clang undefined-behavior-sanitizer"; exit 1; fi + - exit_code5=0 + - exit_code10=0 + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --html=report-5ms.html --self-contained-html --junit-xml=report-junit-5ms.xml --dut_fr 5 --decoder_only || exit_code5=$? + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --html=report-10ms.html --self-contained-html --junit-xml=report-junit-10ms.xml --dut_fr 10 --decoder_only || exit_code10=$? + - zero_errors5=$(cat report-junit-5ms.xml | grep -c 'errors="0"') || true + - zero_errors10=$(cat report-junit-10ms.xml | grep -c 'errors="0"') || true + - zero_errors=1 + - if [ $zero_errors5 != 1 ]; then echo "run error in with 5ms rendering encountered"; zero_errors=0 ; fi + - if [ $zero_errors10 != 1 ]; then echo "run error in with 10ms rendering encountered"; zero_errors=0 ; fi + - if [ $zero_errors != 1 ]; then exit $EXIT_CODE_FAIL; fi + - if [ $exit_code5 -eq 1 ]; then echo "Non-bitexact cases encountered with 5ms rendering!"; exit_code=1; fi + - if [ $exit_code10 -eq 1 ]; then echo "Non-bitexact cases encountered with 10ms rendering!"; exit_code=1; fi + - if [ $exit_code -eq 1 ]; then exit $EXIT_CODE_FAIL; fi artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" expire_in: 1 week when: always + expose_as: "pytest 5ms and 10ms vs 20ms results" paths: - - report-junit.xml - - report.html - expose_as: "usan selftest results" + - report-junit-5ms.xml + - report-5ms.html + - report-junit-10ms.xml + - report-10ms.html reports: junit: - - report-junit.xml + - report-junit-5ms.xml + - report-junit-10ms.xml # test renderer executable renderer-smoke-test: @@ -1028,7 +1122,7 @@ check-first-frame-is-sid: expose_as: "logs-sidstart" expire_in: "5 days" -lc3plus-ensure-no-code-changes: +.lc3plus-ensure-no-code-changes: extends: - .test-job-linux - .rules-merge-request @@ -1043,6 +1137,29 @@ lc3plus-ensure-no-code-changes: - modified_files=$(git status -s) - if [[ $modified_files ]]; then printf 'LC3plus codebase was modified!\n\n'"$modified_files"'\n\n'; exit $EXIT_CODE_FAIL; fi +check-bitexactness-hrtf-rom-and-file: + extends: + - .test-job-linux + - .rules-merge-request + stage: test + needs: ["build-codec-linux-cmake"] + timeout: "5 minutes" + script: + - *print-common-info + - cmake . + - make -j + - python3 tests/create_short_testvectors.py --which all --cut_len 1.0 + - python3 -m pytest tests/hrtf_binary_loading --html=report.html --junit-xml=report-junit.xml --self-contained-html + artifacts: + paths: + - report.html + - report-junit.xml + when: always + name: "$CI_JOB_NAME--$CI_MERGE_REQUEST_ID--sha-$CI_COMMIT_SHA--hrtf-loading" + expose_as: "logs-hrtf-loading" + expire_in: "5 days" + + # --------------------------------------------------------------- # Test jobs for main branch # --------------------------------------------------------------- @@ -1214,6 +1331,166 @@ test-be-to-release: expose_as: "test-be-to-release results" +ivas-conformance: + tags: + - ivas-windows + stage: test + timeout: "60 minutes" + rules: + - if: ($CI_PIPELINE_SOURCE == 'web' || $CI_PIPELINE_SOURCE == 'trigger') && $MANUAL_PIPELINE_TYPE == 'ivas-conformance' + allow_failure: + exit_codes: + - 123 + script: + - *print-common-info-windows + # Prepare reference exec, use tests and scripts from reference + - $source_branch_commit_sha = $(git rev-parse HEAD) + - git checkout main # This should be set to a relevant reference + - git pull # Ensure to get the latest version + - python .\scripts\strip_split_rendering.py + - MSBuild.exe -maxcpucount .\Workspace_msvc\Workspace_msvc.sln /property:Configuration=Debug + - cp -force IVAS_cod.exe IVAS_cod_ref.exe + - cp -force IVAS_dec.exe IVAS_dec_ref.exe + - cp -force IVAS_rend.exe IVAS_rend_ref.exe + - git restore . + - git checkout $source_branch_commit_sha + + # Reference creation + - python tests/create_short_testvectors.py + - python scripts/prepare_combined_format_inputs.py + - python -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref --keep_files + - python -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref_part2 --keep_files + - python -m pytest tests/renderer/test_renderer.py --create_ref --keep_files + + # Output creation + - python -m pytest tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html + - python scripts/parse_commands.py report_cmd.html Readme_IVAS.txt + + # Copy input data and output ref data + - if (Test-Path testvec) {rm -r -force testvec} + - mkdir testvec + - mkdir testvec/binauralRenderer_interface + - mkdir testvec/testv + - mkdir testvec/testv/renderer + - mkdir testvec/bin + - cp -r -force -ErrorAction Ignore scripts/testv/* testvec/testv + - cp -r -force -ErrorAction Ignore scripts/ls_layouts testvec + - cp -r -force -ErrorAction Ignore scripts/switchPaths testvec + - cp -r -force -ErrorAction Ignore scripts/trajectories testvec + - cp -r -force -ErrorAction Ignore scripts/binauralRenderer_interface/binaural_renderers_hrtf_data testvec/binauralRenderer_interface + - cp -r -force -ErrorAction Ignore tests/ref testvec/testv/ref + - cp -r -force -ErrorAction Ignore tests/dut/* testvec/testv/ref + - cp -r -force -ErrorAction Ignore tests/renderer/cut testvec/testv/renderer/ref + - cp -r -force -ErrorAction Ignore tests/conformance-test testvec/ + - cp Readme_IVAS_dec.txt testvec + - cp Readme_IVAS_enc.txt testvec + - cp Readme_IVAS_rend.txt testvec + - cp Readme_IVAS_JBM_dec.txt testvec + - cp IVAS_cod.exe testvec/bin + - cp IVAS_dec.exe testvec/bin + - cp IVAS_rend.exe testvec/bin + + # Test run generated scripts in testvec + - cd testvec + - python -m pytest conformance-test/test_26252.py --junit-xml=report-junit.xml --html=report.html --self-contained-html + - mv report.html .. + - mv report-junit.xml .. + + artifacts: + name: "ivas-conformance-$CI_COMMIT_SHORT_SHA" + expire_in: 1 week + when: always + paths: + - report-junit.xml + - report.html + - Readme_IVAS_dec.txt + - Readme_IVAS_enc.txt + - Readme_IVAS_rend.txt + - Readme_IVAS_JBM_dec.txt + expose_as: "Draft IVAS conformance" + reports: + junit: report-junit.xml + +ivas-conformance-linux: + tags: + - ivas-linux + stage: test + timeout: "60 minutes" + rules: + - if: ($CI_PIPELINE_SOURCE == 'web' || $CI_PIPELINE_SOURCE == 'trigger') && $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + allow_failure: + exit_codes: + - 123 + script: + - *print-common-info + # Prepare reference exec, use tests and scripts from reference + - source_branch_commit_sha=$(git rev-parse HEAD) + - git checkout main # This should be set to a relevant reference + + - make -j + - cp IVAS_cod IVAS_cod_ref + - cp IVAS_dec IVAS_dec_ref + - cp IVAS_rend IVAS_rend_ref + - git restore . + - git checkout $source_branch_commit_sha + + # Reference creation + - python3 tests/create_short_testvectors.py + - python3 scripts/prepare_combined_format_inputs.py + - python3 -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref --keep_files + - python3 -m pytest tests/codec_be_on_mr_nonselection -v -n auto --update_ref 1 -m create_ref_part2 --keep_files + - python3 -m pytest tests/renderer/test_renderer.py --create_ref --keep_files + + # Output creation + - python3 -m pytest tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html + - python3 scripts/parse_commands.py report_cmd.html Readme_IVAS.txt + + # Copy input data and output ref data + - rm -rf testvec + - mkdir testvec + - mkdir testvec/binauralRenderer_interface + - mkdir testvec/testv + - mkdir testvec/testv/renderer + - mkdir testvec/bin + - cp -r scripts/testv/* testvec/testv + - cp -r scripts/ls_layouts testvec + - cp -r scripts/switchPaths testvec + - cp -r scripts/trajectories testvec + - cp -r scripts/binauralRenderer_interface/binaural_renderers_hrtf_data testvec/binauralRenderer_interface + - cp -r tests/ref testvec/testv/ref + - cp -r tests/dut/* testvec/testv/ref + - cp -r tests/renderer/cut testvec/testv/renderer/ref + - cp -r tests/conformance-test testvec/ + - cp Readme_IVAS_dec.txt testvec + - cp Readme_IVAS_enc.txt testvec + - cp Readme_IVAS_rend.txt testvec + - cp Readme_IVAS_JBM_dec.txt testvec + - cp IVAS_cod testvec/bin + - cp IVAS_dec testvec/bin + - cp IVAS_rend testvec/bin + + # Test run generated scripts in testvec + - cd testvec + - python3 -m pytest conformance-test/test_26252.py --junit-xml=report-junit.xml --html=report.html --self-contained-html + - mv report.html .. + - mv report-junit.xml .. + + artifacts: + name: "ivas-conformance-linux-$CI_COMMIT_SHORT_SHA" + expire_in: 1 week + when: always + paths: + - report-junit.xml + - report.html + - Readme_IVAS_dec.txt + - Readme_IVAS_enc.txt + - Readme_IVAS_rend.txt + - Readme_IVAS_JBM_dec.txt + expose_as: "Draft IVAS conformance -- Linux" + reports: + junit: report-junit.xml + + test-long-self-test: tags: - ivas-linux-fast @@ -1240,6 +1517,7 @@ test-long-self-test: ### switch to main - git checkout main + - git pull origin main - echo "Building reference codec at commit $(git rev-parse HEAD)" ### build main (ref) binaries @@ -1287,6 +1565,56 @@ test-long-self-test: # --------------------------------------------------------------- # Scheduled jobs on main # --------------------------------------------------------------- + +# code selftest long testvectors with memory-sanitizer binaries +ltv-msan: + extends: + - .sanitizer-selftest-ltv + rules: + - if: $SANITIZER_SCHEDULE_E + timeout: 2 hour + tags: + - ivas-linux-fast + before_script: + - CLANG_NUM=1 + - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS + - SELF_TEST_PRM_FILE="tests/test_param_file_ltv.py" + <<: *sanitizer-selftest-anchor + +# code selftest long testvectors with address-sanitizer binaries +ltv-asan: + extends: + - .sanitizer-selftest-ltv + rules: + - if: $SANITIZER_SCHEDULE_E + when: delayed + start_in: 2 hours + tags: + - ivas-linux-fast + timeout: 2 hour + before_script: + - CLANG_NUM=2 + - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS + - SELF_TEST_PRM_FILE="tests/test_param_file_ltv.py" + <<: *sanitizer-selftest-anchor + +# code selftest long testvectors with undefined-behaviour-sanitizer binaries +ltv-usan: + extends: + - .sanitizer-selftest-ltv + rules: + - if: $SANITIZER_SCHEDULE_E + when: delayed + start_in: 3 hours + tags: + - ivas-linux-fast + timeout: 2 hour + before_script: + - CLANG_NUM=3 + - SELFTEST_SANITY_TIMEOUT=$TESTCASE_TIMEOUT_LTV_SANITIZERS + - SELF_TEST_PRM_FILE="tests/test_param_file_ltv.py" + <<: *sanitizer-selftest-anchor + .sanitizer-test-template: extends: - .test-job-linux @@ -1301,6 +1629,8 @@ test-long-self-test: paths: - ep_015.g192 - dly_profile.dat + - head_rot_traj.csv + - exof_traj.csv - ./LOGS_PLC - ./LOGS_noPLC @@ -1832,6 +2162,9 @@ coverage-test-on-main-scheduled: - python3 tests/create_short_testvectors.py - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v -n auto --update_ref 1 -m create_ref --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v -n auto --update_ref 1 -m create_ref_part2 --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + # need to ignore non-zero exit codes as limiter is active and thus the different framesiszes will not be BE in all cases + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --dut_encoder_path ./IVAS_cod --dut_decoder_path ./IVAS_dec --dut_fr 5 --decoder_only || true + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --dut_encoder_path ./IVAS_cod --dut_decoder_path ./IVAS_dec --dut_fr 10 --decoder_only || true - python3 -m pytest -q -n auto tests/renderer/test_renderer.py --create_ref - python3 -m pytest -q -n auto tests/renderer/test_renderer.py --create_cut - lcov -c -d obj -o coverage_stv.info # extract coverage of short test vectors here diff --git a/.gitlab/issue_templates/asan_ltv_error.md b/.gitlab/issue_templates/asan_ltv_error.md new file mode 100644 index 0000000000000000000000000000000000000000..97b3fa9ec200e00894f3d816d72173503de100ee --- /dev/null +++ b/.gitlab/issue_templates/asan_ltv_error.md @@ -0,0 +1,39 @@ +### Basic info + +- Commit SHA: + +### Bug description + +Clang ASAN sanitizer test in pipeline found an error: + + +``` + +``` + + +Link to test pipeline: XXX + +### Ways to reproduce + +Using the [scripts](https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/wikis/Software-development/pyivastest-howto#how-to-reproduce-tests): + + +``` +python3 scripts/IvasBuildAndRunChecks.py --checks CLANG2 -m MODE -p /path/to/my/local/ci_linux_ltv_local.json +``` +or directly: + +``` +make clean +make -j CLANG=2 +./IVAS_cod ... +networkSimulator_g192 dly_profile.dat bit bit_err trace_dump 1 +./IVAS_dec ... +``` + + + +/label ~"Priority::Critical" ~Company: ~Subpart: +/label ~Type:Bug ~Status::ToDo diff --git a/.gitlab/issue_templates/msan_ltv_error.md b/.gitlab/issue_templates/msan_ltv_error.md new file mode 100644 index 0000000000000000000000000000000000000000..cc57222658206e7367e8f90d59f657495f806cf6 --- /dev/null +++ b/.gitlab/issue_templates/msan_ltv_error.md @@ -0,0 +1,46 @@ +### Basic info + +- Commit SHA: + +### Bug description + +Clang MSAN sanitizer test in pipeline found an error: + + +``` + +``` + + +Link to test pipeline: XXX + +### Ways to reproduce + +Activate [origin-tracking](https://clang.llvm.org/docs/MemorySanitizer.html#msan-origins) (more detailed traceback about where the undefined value came from) by appending +``` + -fsanitize-memory-track-origins +``` +in the `Makefile` at lines 71 and 72. Note that this may increase runtime heavily. + +Using the [scripts](https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/wikis/Software-development/pyivastest-howto#how-to-reproduce-tests): + + + +``` +python3 scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m MODE -p /path/to/my/local/ci_linux_ltv_local.json +``` +or directly: + +``` +make clean +make -j CLANG=1 +./IVAS_cod ... +networkSimulator_g192 dly_profile.dat bit bit_err trace_dump 1 +./IVAS_dec ... +``` + + + +/label ~"Priority::Critical" ~Company: ~Subpart: +/label ~Type:Bug ~Status::ToDo diff --git a/.gitlab/issue_templates/sanitizer_error.md b/.gitlab/issue_templates/usan_ltv_error.md similarity index 81% rename from .gitlab/issue_templates/sanitizer_error.md rename to .gitlab/issue_templates/usan_ltv_error.md index e5b42ba2f4183e860100abc462d2d42b136ff957..ef6562e866cb34e629732f58914aa8a8d7462769 100644 --- a/.gitlab/issue_templates/sanitizer_error.md +++ b/.gitlab/issue_templates/usan_ltv_error.md @@ -4,7 +4,7 @@ ### Bug description -Clang (m,a,u)san sanitizer test in pipeline found an error: +Clang USAN sanitizer test in pipeline found an error: ``` @@ -20,15 +20,15 @@ Using the [scripts](https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/wikis/ ``` -python3 scripts/IvasBuildAndRunChecks.py --checks CLANGX -m MODE -p /path/to/my/local/ci_linux_ltv_local.json --usan_supp_file scripts/ubsan.supp +python3 scripts/IvasBuildAndRunChecks.py --checks CLANG3 -m MODE -p /path/to/my/local/ci_linux_ltv_local.json --usan_supp_file scripts/ubsan.supp ``` or directly: ``` make clean -make -j CLANG=X +make -j CLANG=3 ./IVAS_cod ... -eid-xor -vbr -fer bit ep_015.g192 bit_fer +networkSimulator_g192 dly_profile.dat bit bit_err trace_dump 1 ./IVAS_dec ... ``` diff --git a/LICENSE.md b/LICENSE.md index aa9c35e4f9786f3321942cacb1f56d7d91840e20..1c60a85b1afa1ba77ced378f75bed35f3ab214e6 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/apps/decoder.c b/apps/decoder.c index 0c1dc1ab5dc6d3b71ab552f35dfff7eb0208e783..049e3682a07bd28f6d5ef71d42c00140b137a045 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -204,9 +204,7 @@ int main( IVAS_RENDER_FRAMESIZE asked_frame_size; IVAS_DEC_HRTF_HANDLE *hHrtfTD = NULL; IVAS_DEC_HRTF_CREND_HANDLE *hSetOfHRTF = NULL; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics = NULL; -#endif #ifdef DEBUGGING int32_t noClipping; int32_t cnt_frames_limited; @@ -463,9 +461,9 @@ int main( *------------------------------------------------------------------------------------------*/ #ifdef SPLIT_REND_WITH_HEAD_ROT + asked_frame_size = arg.renderFramesize; if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - asked_frame_size = arg.renderFramesize; if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -478,11 +476,6 @@ int main( goto cleanup; } - if ( arg.renderFramesize != asked_frame_size ) - { - fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for split rendering!\n" ); - } - arg.enableHeadRotation = true; } #endif @@ -635,12 +628,23 @@ int main( goto cleanup; } + if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); + goto cleanup; + } + + if ( ( error = RenderConfigReader_getDirectivity( renderConfigReader, arg.directivityPatternId, renderConfig.directivity ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); + goto cleanup; + } + #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( arg.renderFramesize == IVAS_RENDER_FRAMESIZE_5MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - renderConfig.split_rend_config.dof == 0 ) ) + if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) { - /*TODO : needs to be refined as this wont work with LCLD codec*/ - arg.renderFramesize = IVAS_RENDER_FRAMESIZE_5MS; + arg.renderFramesize = asked_frame_size; } else { @@ -652,19 +656,11 @@ int main( return error; } -#endif - - if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); - goto cleanup; - } - - if ( ( error = RenderConfigReader_getDirectivity( renderConfigReader, arg.directivityPatternId, renderConfig.directivity ) ) != IVAS_ERR_OK ) + if ( arg.renderFramesize != asked_frame_size ) { - fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); - goto cleanup; + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); } +#endif if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { @@ -738,16 +734,6 @@ int main( } } -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - if ( ( *hHrtfTD != NULL ) && ( error = load_reverb_binary( *hHrtfTD, hrtfReader ) ) != IVAS_ERR_OK ) - { - if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) - { - fprintf( stderr, "\nError in loading HRTF binary file %s \n\n", arg.hrtfFileName ); - goto cleanup; - } - } -#endif if ( ( error = IVAS_DEC_GetHrtfCRendHandle( hIvasDec, &hSetOfHRTF ) ) != IVAS_ERR_OK ) { @@ -808,7 +794,6 @@ int main( } } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = IVAS_DEC_GetHrtfStatisticsHandle( hIvasDec, &hHrtfStatistics ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_GetHrtfHandle failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -826,7 +811,6 @@ int main( destroy_hrtf_statistics( hHrtfStatistics ); } } -#endif } /*------------------------------------------------------------------------------------------* @@ -909,10 +893,8 @@ cleanup: IVAS_DEC_GetHrtfCRendHandle( hIvasDec, &hSetOfHRTF ); destroy_SetOfHRTF( hSetOfHRTF ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_GetHrtfStatisticsHandle( hIvasDec, &hHrtfStatistics ); destroy_hrtf_statistics( hHrtfStatistics ); -#endif } IVAS_DEC_Close( &hIvasDec ); @@ -2028,6 +2010,7 @@ static ivas_error initOnFirstGoodFrame( { /* Duplicate good first frame metadata to fill the beginning of stream. */ IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -2036,7 +2019,8 @@ static ivas_error initOnFirstGoodFrame( for ( int16_t j = 0; j < numInitialBadFrames; ++j ) { - if ( ( error = MasaFileWriter_writeFrame( *ppMasaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + float delayMs = (float) ( pFullDelayNumSamples[0] ) / (float) ( *delayTimeScale ); + if ( ( error = MasaFileWriter_writeFrame( *ppMasaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( *ppMasaWriter ) ); return error; @@ -2342,7 +2326,7 @@ static ivas_error decodeG192( { if ( ( error = TsmScaleFileReader_readScale( tsmScaleFileReader, &scale ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + fprintf( stderr, "\nError (%s) when reading TSM data from %s \n\n", arg.inputBitstreamFilename, TsmScaleFileReader_getFilePath( tsmScaleFileReader ) ); goto cleanup; } int16_t maxScaling; @@ -2434,7 +2418,6 @@ static ivas_error decodeG192( #endif } } - } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); if ( error == IVAS_ERR_END_OF_FILE ) @@ -2543,13 +2526,22 @@ static ivas_error decodeG192( if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM ) { IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + int16_t fullDelayNumSamples[3]; + float delayMs; + + /* delayNumSamples is zeroed, and delayNumSamples_orig is updated only on first good frame, so need to re-fetch delay info */ + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, fullDelayNumSamples, &delayTimeScale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + } if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } - if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); goto cleanup; @@ -2684,13 +2676,21 @@ static ivas_error decodeG192( if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM ) { IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + int16_t fullDelayNumSamples[3]; + float delayMs; + + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, fullDelayNumSamples, &delayTimeScale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + } if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } - if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); goto cleanup; @@ -3365,13 +3365,22 @@ static ivas_error decodeVoIP( if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM ) { IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + int16_t fullDelayNumSamples[3]; + float delayMs; + + /* delayNumSamples_orig is fetched only for the first good frame, but here the delay can change between frames, so need to re-fetch */ + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, fullDelayNumSamples, &delayTimeScale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + } if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 1 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } - if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); goto cleanup; @@ -3386,7 +3395,10 @@ static ivas_error decodeVoIP( } vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; frame++; - systemTime_ms += systemTimeInc_ms; + if ( vec_pos_update == 0 ) + { + systemTime_ms += vec_pos_len * systemTimeInc_ms; + } #ifdef WMOPS update_mem(); @@ -3394,6 +3406,85 @@ static ivas_error decodeVoIP( #endif } + + int16_t nSamplesFlushed = 0; + + /* decode and get samples */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( nSamplesFlushed ) + { + /* Write current frame */ + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, nSamplesFlushed * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + + /* Write ISm metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM || bsFormat == IVAS_DEC_BS_SBA_ISM ) + { + if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetNumObjects: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + for ( i = 0; i < numObj; ++i ) + { + IVAS_ISM_METADATA IsmMetadata; + + if ( ( error = IVAS_DEC_GetObjectMetadata( hIvasDec, &IsmMetadata, 0, i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetObjectMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( IsmFileWriter_writeFrame( IsmMetadata, ismWriters[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing ISM metadata to file %s\n", IsmFileWriter_getFilePath( ismWriters[i] ) ); + goto cleanup; + } + } + } + + if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM ) + { + IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + int16_t fullDelayNumSamples[3]; + float delayMs; + + /* delayNumSamples is zeroed, and delayNumSamples_orig is updated only on first good frame, so need to re-fetch delay info */ + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, fullDelayNumSamples, &delayTimeScale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + } + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + goto cleanup; + } + } + } + } + /*------------------------------------------------------------------------------------------* * Add zeros at the end to have equal length of synthesized signals *------------------------------------------------------------------------------------------*/ diff --git a/apps/encoder.c b/apps/encoder.c index 21aa5d0b1d489552451f01b734accc94497f1e18..b00f4f75fdc85f3dc72e6ad1a0a9568e70e2a60d 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -686,7 +686,7 @@ int main( { if ( ( error = JbmFileReader_readCAconfig( jbmReader, &caConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "JbmFileReader_readCAconfig() failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); + fprintf( stderr, "\nError (%s) while reading Channel-Aware Config. from: %s\n\n", IVAS_ENC_GetErrorMessage( error ), JbmFileReader_getFilePath( jbmReader ) ); goto cleanup; } diff --git a/apps/renderer.c b/apps/renderer.c index e95f5d5adbb39b4d05c5171f973040e836a986e7..8a9e0b48f84f0745af9cdf84ecc08a362669c8fc 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -747,9 +747,7 @@ int main( IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv = NULL; IVAS_DEC_HRTF_PARAMBIN_HANDLE *hHrtfParambin = NULL; IVAS_DEC_HRTF_HANDLE *hHrtfTD = NULL; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics = NULL; -#endif IsmPositionProvider *positionProvider; LfeRoutingConfig *lfeRoutingConfigs[RENDERER_MAX_MC_INPUTS]; RenderConfigReader *renderConfigReader = NULL; @@ -1037,16 +1035,6 @@ int main( } } -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - if ( ( hHrtfTD != NULL ) && ( error = load_reverb_binary( *hHrtfTD, hrtfFileReader ) ) != IVAS_ERR_OK ) - { - if ( error != IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA ) - { - fprintf( stderr, "\nError in loading HRTF binary file %s: %s \n\n", args.customHrtfFilePath, ivas_error_to_string( error ) ); - goto cleanup; - } - } -#endif if ( ( error = IVAS_REND_GetHrtfCRendHandle( hIvasRend, &hSetOfHRTF ) ) != IVAS_ERR_OK ) { @@ -1105,7 +1093,6 @@ int main( } } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = IVAS_REND_GetHrtfStatisticsHandle( hIvasRend, &hHrtfStatistics ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_REND_GetHrtfStatisticsHandle failed\n\n" ); @@ -1123,7 +1110,6 @@ int main( destroy_hrtf_statistics( hHrtfStatistics ); } } -#endif } hrtfFileReader_close( &hrtfFileReader ); @@ -1903,7 +1889,7 @@ int main( #ifdef SPLIT_REND_WITH_HEAD_ROT for ( i = 0; i < args.inConfig.numBinBuses; ++i ) { - if ( splitBinNeedsNewFrame ) + if ( numSamplesRead > 0 ) { if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) { @@ -1917,7 +1903,9 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - + } + if ( splitBinNeedsNewFrame ) + { if ( ( error = IVAS_REND_FeedSplitBinauralBitstream( hIvasRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -2122,7 +2110,7 @@ int main( } } - if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMetaOutput ) ) != IVAS_ERR_OK ) + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMetaOutput, NULL ) ) != IVAS_ERR_OK ) /* NULL -> use default metadata delay settings */ { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); } @@ -2217,6 +2205,7 @@ cleanup: } split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); #endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) @@ -2229,12 +2218,11 @@ cleanup: RotationFileReader_close( &headRotReader ); RotationFileReader_close( &externalOrientationFileReader ); RotationFileReader_close( &referenceRotReader ); + Vector3PairFileReader_close( &referenceVectorReader ); destroy_td_hrtf( hHrtfTD ); destroy_SetOfHRTF( hSetOfHRTF ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES destroy_hrtf_statistics( hHrtfStatistics ); -#endif IVAS_REND_Close( &hIvasRend ); IsmPositionProvider_close( positionProvider ); RenderConfigReader_close( &renderConfigReader ); diff --git a/ci/build_all_linux.sh b/ci/build_all_linux.sh index 47ad54dc42e9bd43c46744a673915726b924b0db..63beef18f07338294d40eda67333536fceac0635 100755 --- a/ci/build_all_linux.sh +++ b/ci/build_all_linux.sh @@ -1,6 +1,6 @@ #! /usr/bin/bash -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/build_codec_instrumented_linux.sh b/ci/build_codec_instrumented_linux.sh index 7c4da0a7f5176ac155c746b1b30d2f472c4e07b7..2ff293c61396d409a99a2b52c36f3f21121110c4 100755 --- a/ci/build_codec_instrumented_linux.sh +++ b/ci/build_codec_instrumented_linux.sh @@ -1,6 +1,6 @@ #! /usr/bin/bash -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/build_codec_sanitizers_linux.sh b/ci/build_codec_sanitizers_linux.sh index d352fa32ec1cd6d8d3283c4984ba428c117b5769..f599d607ca41504208d52f3ab5f809b0c73859fc 100755 --- a/ci/build_codec_sanitizers_linux.sh +++ b/ci/build_codec_sanitizers_linux.sh @@ -1,6 +1,6 @@ #! /usr/bin/bash -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/collect_artifacts.py b/ci/collect_artifacts.py index d3228ba2e85e224fa7fb9fdc6415036b6c77f982..c67445e51cdbc67e190622e8ee0387abd0ed61a8 100755 --- a/ci/collect_artifacts.py +++ b/ci/collect_artifacts.py @@ -1,9 +1,8 @@ #! /usr/bin/env python3 -import pathlib import argparse +import pathlib import re - TEST_TYPES = ["sanitizers"] @@ -15,39 +14,20 @@ def main(args): collect_for_sanitizer_test(file) -def find_failed_files_for_sanitizer_test( - console_log: list, subfolder: str, which="LOGS" -) -> dict(): - - assert which in ["LOGS", "FILE_BASENAMES"] +def find_failed_files_for_sanitizer_test(console_log: list) -> dict(): - pattern_line = "(Encoding|Decoding) failed .*for \/.*(CLANG.|VALGRIND)\/(.*)" - pattern_file = "(.*_b[0-9]*_.*_rs|.*_b[0-9]*_.*_cbr).*" + pattern_line = r"(CLANG.) reports . error\(s\) for (.*)" files_found = dict() for line in console_log: m_line = re.match(pattern_line, line) if m_line is not None: - _, test, filename = m_line.groups() - filename = pathlib.Path(filename).name - m_file = re.match(pattern_file, filename) - if m_file is None: - print(f"Unexpected: no match on {filename} with {pattern_file} - skip") - continue - filename_start = m_file.groups()[0] - - if which == "LOGS": - folder = pathlib.Path(f"{test}/{subfolder}/") - files = [ - f for f in folder.iterdir() if f.name.startswith(filename_start) - ] - elif which == "FILE_BASENAMES": - files = [filename_start] + test, filename = m_line.groups() if test in files_found: - files_found[test].extend(files) + files_found[test].append(filename) else: - files_found[test] = files + files_found[test] = [filename] return files_found @@ -57,16 +37,20 @@ def collect_for_sanitizer_test(file): with open(file) as f: console_log = f.readlines() - files_to_archive_noPLC = find_failed_files_for_sanitizer_test( - console_log, "logs_noPLC" - ) - files_to_archive = find_failed_files_for_sanitizer_test(console_log, "logs") + start_indicators = ["Adding config" in l for l in console_log] + idx_first_run = start_indicators.index(True) + idx_second_run = start_indicators[idx_first_run + 1:].index(True) + idx_first_run + 1 + no_plc_part = console_log[idx_first_run:idx_second_run] + plc_part = console_log[idx_second_run:] + + files_to_archive_noPLC = find_failed_files_for_sanitizer_test(no_plc_part) + files_to_archive_PLC = find_failed_files_for_sanitizer_test(plc_part) log_folder = pathlib.Path("./LOGS_PLC") log_folder.mkdir() - for test in files_to_archive.keys(): + for test in files_to_archive_PLC.keys(): log_folder.joinpath(test).mkdir() - for test, files in files_to_archive.items(): + for test, files in files_to_archive_PLC.items(): folder = log_folder.joinpath(test) for p in files: source = pathlib.Path(p) @@ -80,7 +64,7 @@ def collect_for_sanitizer_test(file): for test, files in files_to_archive_noPLC.items(): folder = log_folder_noPLC.joinpath(test) for p in files: - source = pathlib.Path(p) + source = pathlib.Path(p.replace("/logs/", "/logs_noPLC/")) target = folder.joinpath(source.name) source.rename(target) diff --git a/ci/combine_genpatt_and_jbm_profile.py b/ci/combine_genpatt_and_jbm_profile.py index b039ceb99002d8743e0122c3f157eb0abdbb24b8..4d2fd38a0042723d655718547d238a570dbb627d 100644 --- a/ci/combine_genpatt_and_jbm_profile.py +++ b/ci/combine_genpatt_and_jbm_profile.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -30,8 +30,8 @@ """ import argparse -import numpy as np +import numpy as np ERR_MAGIC_NUM_DLY_PROF = -1 ERR_MAGIC_NUM_G192 = 27424 @@ -54,7 +54,7 @@ def combine_error_profiles(genpatt_file, jbm_dly_profile, output_file): # insert lost frames based on .g192 file err_idx = np.where(ep == ERR_MAGIC_NUM_G192)[0] dly[err_idx] = -1 - + with open(output_file, "w") as f: for d in dly: f.write(f"{int(d)}\n") diff --git a/ci/comment_defines.py b/ci/comment_defines.py index 0b6e3457035e0dc93d930dbe046c18a8437c3e8c..7f6a77af4bdc15fb8d90ffcdf4e1709cd754ff21 100755 --- a/ci/comment_defines.py +++ b/ci/comment_defines.py @@ -1,5 +1,5 @@ -import re import argparse +import re def process_file(file_path: str, defines_re): @@ -13,7 +13,9 @@ def process_file(file_path: str, defines_re): for i, line in enumerate(lines): for name, regex in defines_re.items(): # Spaces are replaced with underscores to avoid matching on multiple runs - lines[i] = regex.sub(lambda x: f"/* {x.group(0).replace(' ', '_')} */", line) + lines[i] = regex.sub( + lambda x: f"/* {x.group(0).replace(' ', '_')} */", line + ) if lines[i] != line: num_subbed[name] += 1 @@ -41,7 +43,9 @@ def main(args): if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Comment out preprocessor defines in c/c++ files") + parser = argparse.ArgumentParser( + description="Comment out preprocessor defines in c/c++ files" + ) parser.add_argument("-f", "--files", nargs="+", required=True, type=str) parser.add_argument("-d", "--defines", nargs="+", required=True, type=str) main(parser.parse_args()) diff --git a/ci/complexity_measurements/genWebpageData_Ram.csh b/ci/complexity_measurements/genWebpageData_Ram.csh index d6e5a842e3b04a5bde4735f6e2b6c197befe053c..c0e3eab411a23ddd2b798859d71b0cd12be6008f 100755 --- a/ci/complexity_measurements/genWebpageData_Ram.csh +++ b/ci/complexity_measurements/genWebpageData_Ram.csh @@ -1,6 +1,6 @@ #!/bin/tcsh -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/complexity_measurements/genWebpageData_Rom.csh b/ci/complexity_measurements/genWebpageData_Rom.csh index 801dfda724738bfbbfdcb4ddcef8b5107c66f66c..d2ed0b3f949b252e651ae261ea11afb2861ee2c7 100755 --- a/ci/complexity_measurements/genWebpageData_Rom.csh +++ b/ci/complexity_measurements/genWebpageData_Rom.csh @@ -1,6 +1,6 @@ #!/bin/tcsh -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/complexity_measurements/genWebpageData_WMOPS.csh b/ci/complexity_measurements/genWebpageData_WMOPS.csh index 4993ae81f219405d04e9634101ee0c5b2c8cfdb4..8e052210c8ea9879ff5eba25041a66520cdb631c 100755 --- a/ci/complexity_measurements/genWebpageData_WMOPS.csh +++ b/ci/complexity_measurements/genWebpageData_WMOPS.csh @@ -1,6 +1,6 @@ #!/bin/tcsh -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/complexity_measurements/genWebpageData_WmopPerOperatingpoint.csh b/ci/complexity_measurements/genWebpageData_WmopPerOperatingpoint.csh index 3d9d9d448c27fdce30724273e633cdf3697fdc0d..906d08c949b015fc6c6bb0f96a11d22c01eab187 100755 --- a/ci/complexity_measurements/genWebpageData_WmopPerOperatingpoint.csh +++ b/ci/complexity_measurements/genWebpageData_WmopPerOperatingpoint.csh @@ -1,6 +1,6 @@ #!/bin/tcsh -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/complexity_measurements/getWmops.sh b/ci/complexity_measurements/getWmops.sh index e81575892bbead122c6770e92715ebb04b5f0299..22ca8335fb91db0a057d953d7136732d62f796e9 100755 --- a/ci/complexity_measurements/getWmops.sh +++ b/ci/complexity_measurements/getWmops.sh @@ -1,6 +1,6 @@ #! /bin/bash -# (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +# (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, # Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., # Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, # Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/ci/complexity_measurements/index_complexity.html b/ci/complexity_measurements/index_complexity.html index 0e2ec822fa6d8318ebd7463bb48c29dc0c1ea41d..c4972eff5d5965bf34dba42614f749a33d5cfcd8 100755 --- a/ci/complexity_measurements/index_complexity.html +++ b/ci/complexity_measurements/index_complexity.html @@ -1,7 +1,7 @@ gains [ 1.0, 32767/32768.0(first table value used) , first muted, .... ]*/ + /* burst_att_thresh ==5 --> gains [ 1.0, 1.0, 1,0 1,0, 32767/32768.0(first table value used) , first muted,... ]*/ + /* beta_mute_thr ==4 --> start of final attenuation attenuate AvgMix */ +#endif + /* tabled {att_per_frame_idx_p3dB , burst_att_thresh, beta_mute_thr } */ + { 1, 2, 0 + 2 + 2 }, /* 30 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=0 */ + { 1, 3, 0 + 3 + 2 }, /* 40 ms, 0.3 dB delta att in slow mutephase */ + { 3, 3, 1 + 3 + 1 }, /* 50 ms, 0.3 dB delta att in slow mutephase */ + { 3, 4, 1 + 4 + 1}, /* 60 ms, 0.3 dB delta att in slow mutephase */ + { 5, 4, 3 + 4 + 1 }, /* 70 ms, 0.3 dB delta att in slow mutephase */ + { 5, 5, 3 + 5 + 1 }, /* 80 ms, 0.3 dB delta att in slow mutephase */ + { 7, 5, 7 + 5 }, /* 90 ms, 0.3 dB delta att in slow mutephase */ + { 7, 5, 7 + 5 + 1}, /* 100 ms, 0.3 dB delta att in slow mutephase */ + { 9, 5, 9 + 5 }, /* 110 ms, 0.3 dB delta att in slow mutephase */ + { 9, 5, 9 + 5 + 1}, /* 120 ms, 0.3 dB delta att in slow mutephase nominal_fadeout=1 */ + { 11, 5, 15 + 5 },/* 130 ms, 0.3 dB delta att in slow mutephase */ + { 11, 6, 15 + 6 },/* 140 ms, 0.3 dB delta att in slow mutephase nominal 3GPP */ + +}; +#if 0 +/*fade_scheme_tab[ind][0] att_per _fram_index , "points" to first column in POW_ATT TABLES */ +/*fade_scheme_tab[ind][1] is burst_att_thresh, the number of non_muted 1.0 gain frames */ +/*fade_scheme_tab[ind][2] is beta_mute_thr, the location of the start of final muting */ +#endif + + + +/*compressed ATH Abolute hearing THreshold function weights at band borders */ +const LC3_FLOAT scATHFx[MAX_LGW - 2] = { .455444335937500 , 0.930755615234375 , 0.973083496093750 , 0.999969482421875 , 0.908508300781250 , 0.775665283203125 , 0.5 }; +#endif + const LC3_FLOAT PhECU_whr16ms_NB[128]={ 8.000000000000002e-02, 8.393536376804722e-02, 9.567411990702857e-02, 1.150154150448081e-01, 1.416283142591582e-01, 1.750574634660318e-01, 2.147308806541882e-01, 2.599697426559885e-01, 3.099999999999999e-01, 3.639656211120587e-01, @@ -3801,3 +6340,7 @@ const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[] = { const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484 }; +#if defined(CR8_A_PLC_FADEOUT_TUNING) +const LC3_INT16 plc_fadeout_param_maxlen[4] = {800, 400, 266, 200}; +const LC3_INT16 plc_fadeout_param_maxbytes[4] = {27, 14, 9, 7}; +#endif diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h index c0c9e286e55c72bd40851c91fe7229e22d9ef261..6d58a5798addb1c4f07581a6d53d811c08604e40 100644 --- a/lib_lc3plus/constants.h +++ b/lib_lc3plus/constants.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef CONSTANTS_H #define CONSTANTS_H +#include "options.h" #include "defines.h" #include "structs.h" @@ -18,13 +19,15 @@ extern const Complex dct2_16[16]; /* Ari coder */ -extern const LC3_INT ari_tns_order_cf[2][9]; -extern const LC3_INT ari_tns_freq_cf[8][18]; +extern const LC3_INT16 ari_tns_order_cf[2][9]; +extern const LC3_INT16 ari_tns_freq_cf[8][18]; extern const LC3_INT ari_spec_lookup_fl[4096]; -extern const LC3_INT ari_spec_cumfreq_fl[64][18]; +extern const LC3_INT16 ari_spec_cumfreq_fl[64][18]; extern const LC3_INT ari_spec_bits_fl[64][17]; /* SNS */ +extern const LC3_FLOAT sns_W[6]; +extern const LC3_FLOAT *sns_preemph_all[6]; extern const LC3_FLOAT sns_LFCB[8][32]; extern const LC3_FLOAT sns_HFCB[8][32]; extern const LC3_INT pvq_enc_A[16][11]; @@ -128,6 +131,16 @@ extern const LC3_INT BW_cutoff_bin_all_5ms_HR[MAX_BW_BANDS_NUMBER]; extern const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER]; extern const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER]; +#ifdef CR8_G_ADD_75MS +extern const LC3_INT BW_cutoff_bin_all_7_5ms[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT bands_number_7_5ms[6]; +extern const LC3_INT bands_number_7_5ms_HR[6]; +extern const LC3_INT* BW_warp_idx_start_all_7_5ms[4]; +extern const LC3_INT* BW_warp_idx_stop_all_7_5ms[4]; +extern const LC3_INT brickwall_dist_7_5ms[4]; +extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_7_5ms[]; +#endif + /* Arithmetic coding */ extern const LC3_INT tns_cf[8][18]; extern const LC3_INT tns_freq_cf[2][9]; @@ -150,7 +163,6 @@ extern const LC3_FLOAT MDCT_WINDOW_480_2_5ms[240]; extern const LC3_FLOAT* MDCT_WINS_2_5ms[2][6]; extern const LC3_INT MDCT_la_zeroes_2_5ms[6]; - extern const LC3_FLOAT MDCT_WINDOW_80_5ms[80]; extern const LC3_FLOAT MDCT_WINDOW_160_5ms[160]; extern const LC3_FLOAT MDCT_WINDOW_240_5ms[240]; @@ -159,12 +171,15 @@ extern const LC3_FLOAT MDCT_WINDOW_480_5ms[480]; extern const LC3_FLOAT* MDCT_WINS_5ms[2][6]; extern const LC3_INT MDCT_la_zeroes_5ms[6]; -extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; - -extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6]; - +#ifdef CR8_G_ADD_75MS +extern const LC3_FLOAT* MDCT_WINS_7_5ms[2][6]; +extern const LC3_INT32 MDCT_la_zeroes_7_5ms[6]; +#endif +extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; +extern const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6]; extern const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6]; +extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6]; /* Per band energy */ extern const LC3_INT* ACC_COEFF_PER_BAND[6]; @@ -173,17 +188,31 @@ extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5]; +#ifdef CR8_G_ADD_75MS +extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms_HR[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_7_5ms[5]; +#endif extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; /* Near Nyquist detector */ extern const LC3_INT NN_thresh; - +/* Tone detector */ +#ifdef CR8_E_TONE_DETECTOR +extern const LC3_INT32 TD_HR_thresh_10ms; +extern const LC3_INT32 TD_HR_thresh_7_5ms; +extern const LC3_INT32 TD_HR_thresh_5ms; +extern const LC3_INT32 TD_HR_thresh_2_5ms; +#endif // CR8_E_TONE_DETECTOR extern const LC3_INT32 xavg_N_grp[5]; extern const LC3_FLOAT *hannOla_wins[5]; extern const LC3_INT32 gwlpr[MAX_LGW+1]; +#ifdef CR8_A_PLC_FADEOUT_TUNING +extern const LC3_INT16 fade_scheme_tab[24 / 2][3]; +extern const LC3_FLOAT scATHFx[MAX_LGW - 2]; +#endif extern const LC3_INT32 mdct_grp_bins[10]; extern const LC3_FLOAT* PhECU_whr16ms_wins[5]; @@ -200,4 +229,9 @@ extern const LC3_FLOAT plc_tdc_lpc_48[17]; extern const LC3_FLOAT plc_tdc_lpc_96[17]; extern const LC3_FLOAT plc_tdc_lpc_8_25ms[9]; +#if defined(CR8_A_PLC_FADEOUT_TUNING) +extern const LC3_INT16 plc_fadeout_param_maxlen[4]; +extern const LC3_INT16 plc_fadeout_param_maxbytes[4]; #endif + +#endif /* CONSTANTS_H */ diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c index 642b2afda2ef1848f5b232a4caf9d0770db6ef57..c2d37312eb17c23d750b816d34a6c46d7cd49888 100644 --- a/lib_lc3plus/cutoff_bandwidth.c +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,7 +13,7 @@ void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) { - LC3_INT i = 0; + LC3_INT i; if (len > bw_bin){ for (i = -1; i < 3; i++) { diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c index 8fd5784b287477aeffd3ee987e81527f755f2163..9b12627d71e53e585d771098c839cfb87fcf0d5e 100644 --- a/lib_lc3plus/dct4.c +++ b/lib_lc3plus/dct4.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -30,18 +30,17 @@ void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) { Complex tmp1[MAX_LEN]; Complex tmp2[MAX_LEN]; - int i = 0; - const int len = dct->length; + int i; assert(input != output); - for (i = 0; i < len / 2; i++) { + for (i = 0; i < 8; i++) { tmp1[i] = cmplx(input[i * 2], 0); - tmp1[len - i - 1] = cmplx(input[i * 2 + 1], 0); + tmp1[16 - i - 1] = cmplx(input[i * 2 + 1], 0); } fft_apply(&dct->fft, tmp1, tmp2); - for (i = 0; i < len; i++) { + for (i = 0; i < 16; i++) { output[i] = cmul(tmp2[i], dct2_16[i]).r; } output[0] /= (LC3_FLOAT)1.414213562373095; /* SQRT(2) */ @@ -50,7 +49,7 @@ void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) void dct4_init(Dct4* dct, int length) { - int i = 0; + int i; assert(length <= MAX_LEN); dct->length = length; dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); @@ -81,13 +80,13 @@ void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); assert(input != output); - for (i = 0; i < len / 2; i++) { + for (i = 0; i < len >> 1; i++) { tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); } fft_apply(&dct->fft, tmp1, tmp2); - for (i = 0; i < len / 2; i++) { + for (i = 0; i < len >> 1; i++) { Complex t = cmul(tmp2[i], dct->twid2[i]); output[i * 2] = t.r * norm; output[len - i * 2 - 1] = -t.i * norm; diff --git a/lib_lc3plus/dec_entropy.c b/lib_lc3plus/dec_entropy.c index d8512a1068b49c042f627936fa46b0b3df21339b..f072b82d6f7c62847cdf40d9631654f95df8d63f 100644 --- a/lib_lc3plus/dec_entropy.c +++ b/lib_lc3plus/dec_entropy.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -32,7 +32,7 @@ void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val) { - LC3_INT bit = 0, i = 0; + LC3_INT bit, i; read_bit_fl(ptr, mask_side, bp_side, val); @@ -131,8 +131,8 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_ LC3_INT* lsbMode, LC3_INT frame_dms) { - LC3_INT plc_trigger_bw = 0, plc_trigger_last_nz = 0, plc_trigger_SNS1 = 0, plc_trigger_SNS2 = 0, tmp = 0, bit = 0, - submodeMSB = 0, i = 0, ltpf_tmp[3] = {0}, ind = 0, submodeLSB = 0, bp_side_local = 0, mask_side_local = 0; + LC3_INT plc_trigger_bw, plc_trigger_last_nz, plc_trigger_SNS1, plc_trigger_SNS2, tmp, bit, + submodeMSB, i, ltpf_tmp[3], ind, submodeLSB, bp_side_local, mask_side_local; LC3_UINT8* ptr; LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; @@ -174,7 +174,7 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_ } /* Last non-zero tuple */ - read_uint_fl(ceil(LC3_LOGTWO(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); + read_uint_fl(ceil(LC3_LOGTWO(N >> 1)), ptr, &mask_side_local, &bp_side_local, lastnz); *lastnz = (*lastnz + 1) * 2; if (*lastnz > N) { diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c index 88c528b0f639178567a55b87a2084a20cc9b8864..7389ffa53e3dd15d57c9ddd55686478bca71c264 100644 --- a/lib_lc3plus/dec_lc3_fl.c +++ b/lib_lc3plus/dec_lc3_fl.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -58,17 +58,13 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs bfi = 2; switch (decoder->frame_dms) { -# ifdef ENABLE_025_DMS_MODE case 25: max_bw_stopband = max_bw_stopband >> 2; break; -# endif -# ifdef ENABLE_050_DMS_MODE case 50: max_bw_stopband = max_bw_stopband >> 1; break; -# endif -# ifdef ENABLE_075_DMS_MODE +# ifdef CR8_G_ADD_75MS case 75: max_bw_stopband = 3 * (max_bw_stopband >> 2); break; @@ -151,7 +147,11 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs &h_DecSetup->PlcAdvSetup->cum_fading_slow, &h_DecSetup->PlcAdvSetup->cum_fading_fast, h_DecSetup->PlcSetup.q_d_prev, h_DecSetup->sqQdec_fl, h_DecSetup->spec_inv_idx, decoder->yLen, bfi, decoder->frame_dms, h_DecSetup->concealMethod, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_param[0], - &h_DecSetup->PlcAdvSetup->cum_fflcAtten); + &h_DecSetup->PlcAdvSetup->cum_fflcAtten +#ifdef CR8_A_PLC_FADEOUT_TUNING + , h_DecSetup->PlcAdvSetup->plc_fadeout_type +#endif + ); /* IMDCT */ if (h_DecSetup->concealMethod == 4 || bfi != 1 ) @@ -171,6 +171,9 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs bfi, h_DecSetup->ltpf_param, h_DecSetup->ltpf_param_mem, h_DecSetup->ltpf_conf_beta_idx, h_DecSetup->ltpf_conf_beta, h_DecSetup->concealMethod, h_DecSetup->alpha , &h_DecSetup->ltpf_mem_active +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , &h_DecSetup->rel_pitch_change, decoder->hrmode, decoder->frame_dms +#endif ); { diff --git a/lib_lc3plus/defines.h b/lib_lc3plus/defines.h index d978fa4e15e73671ee23cb4eedad8eb9b681ba01..d9251c018199acd00168afb1398a7782c8c3e3b5 100644 --- a/lib_lc3plus/defines.h +++ b/lib_lc3plus/defines.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef DEFINES_H #define DEFINES_H +#include "options.h" #include "stdint.h" @@ -24,13 +25,14 @@ typedef int8_t LC3_INT8; typedef uint32_t LC3_UINT32; /* Release defines */ -// #define ENABLE_2_5MS_MODE +#define ENABLE_2_5MS_MODE #define ENABLE_5MS_MODE +#define ENABLE_075_DMS_MODE #define ENABLE_10_MS_MODE #define ENABLE_ADVANCED_PLC_FL #define ENABLE_ADVANCED_PLC_FL_DEFAULT #define ENABLE_BW_CONTROLLER -//#define ENABLE_HR_MODE_FL +#define ENABLE_HR_MODE_FL #define ENABLE_PADDING #define ENABLE_RFRAME_FL #define ENABLE_PLC @@ -41,20 +43,89 @@ typedef uint32_t LC3_UINT32; #define ENABLE_FRAME_MS_FLAG #define ENABLE_HR_MODE_FL_FLAG +#define CR8_G_ADD_75MS + #ifndef NO_POST_REL_CHANGES /* Post-release non-bitexact changes */ +#define CR8_A_PLC_FADEOUT_TUNING /* Adapt PLC fadeout to avoid gaps in signal */ +#define CR9_D_FLOATING_POINT_CODE_SIMPLIFICATIONS +#define CR9_F_PITCH_WIN_LEN_FIX /* Increase window length for pitch calculation */ +#define CR9_G_IMPROVE_TDC /* summarize G,H,J,L,N */ +#ifdef CR9_G_IMPROVE_TDC +# define CR9_G_PLC_NS_TDC_FIX /* Always use TDC if pitch > 0 */ +# define CR9_H_REMOVE_SWITCH_TO_PLC_NS +# define CR9_J_SLOW_TDC_FADEOUT +# define CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +# ifdef ENABLE_HR_MODE_FL +# ifdef PLC_TUNING_SHORT_FADEOUT +# define CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH +# endif +# endif +#endif /* CR9_G_IMPROVE_TDC */ +#define CR9_I_INC_TDC_FADEOUT_LEN +#define CR9_K_REDUCE_NORM_CORR_TH #endif /* NO_POST_REL_CHANGES */ +#ifdef CR9_D_FLOATING_POINT_CODE_SIMPLIFICATIONS +# define CR9_SIMPLIFY_LOOP +# define CR9_LTPF_REWRITE +# define CR9_QUANT_SPEC_REWRITE +# define CR9_SIMPLIFY_ARI_DECODER +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING +#define MAX_UINT8 255 +# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +# ifdef CR9_K_REDUCE_NORM_CORR_TH +# define THRESH_100_DMS_TDC_CNT 9 +# define THRESH_100_DMS_NS_CNT 7 +# define THRESH_100_DMS_TDC_NS_CNT 73 +# define THRESH_075_DMS_TDC_CNT 7 +# define THRESH_075_DMS_NS_CNT 7 +# define THRESH_075_DMS_TDC_NS_CNT 87 +# define THRESH_050_DMS_TDC_CNT 22 +# define THRESH_050_DMS_NS_CNT 15 +# define THRESH_050_DMS_TDC_NS_CNT 141 +# define THRESH_025_DMS_TDC_CNT 20 +# define THRESH_025_DMS_NS_CNT 21 +# define THRESH_025_DMS_TDC_NS_CNT 278 +# else +# define THRESH_100_DMS_TDC_CNT 3 +# define THRESH_100_DMS_NS_CNT 35 +# define THRESH_100_DMS_TDC_NS_CNT 114 +# define THRESH_075_DMS_TDC_CNT 6 +# define THRESH_075_DMS_NS_CNT 37 +# define THRESH_075_DMS_TDC_NS_CNT 130 +# define THRESH_050_DMS_TDC_CNT 12 +# define THRESH_050_DMS_NS_CNT 55 +# define THRESH_050_DMS_TDC_NS_CNT 227 +# define THRESH_025_DMS_TDC_CNT 10 +# define THRESH_025_DMS_NS_CNT 138 +# define THRESH_025_DMS_TDC_NS_CNT 431 +# endif +# else +# define FAC1_FADEOUT 0.2 +# define FAC2_FADEOUT 1.5 +# define FAC3_FADEOUT 1.75 +# endif +#define REL_PITCH_THRESH 0.36 +#define PLC_LONGTERM_ANALYSIS_MS 200 /* Analysis window 2000 ms / 10 ms */ + +#define PLC_LONGTERM_ANALYSIS_STARTUP_FILL 0.5f /* required buffer fill amount, set to 0.0 to not require any fill at all */ + + +#endif + /* Precision Defines */ -#define LC3_FABS(x) (fabsf(x)) -#define LC3_POW(x, y) (powf(x, y)) +#define LC3_FABS(x) (fabsf(x)) +#define LC3_POW(x, y) (powf(x, y)) #define LC3_LOGTEN(x) (log10f(x)) -#define LC3_LOGTWO(x) (log2f(x)) -# define LC3_COS(x) (cos(x)) -# define LC3_SIN(x) (sin(x)) -#define LC3_SQRT(x) (sqrtf(x)) -#define LC3_EXP(x) (expf(x)) +#define LC3_LOGTWO(x) (log2f(x)) +#define LC3_COS(x) (cos(x)) +#define LC3_SIN(x) (sin(x)) +#define LC3_SQRT(x) (sqrtf(x)) +#define LC3_EXP(x) (expf(x)) # define MAX_BR 320000 /* 400 * 800 */ # define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ @@ -62,10 +133,20 @@ typedef uint32_t LC3_UINT32; # define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ # define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ # define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ - # define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ # define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ +#ifdef CR8_G_ADD_75MS +# define MIN_BR_075DMS_48KHZ_HR ((int)124800/ 800/2)* 800 +# define MIN_BR_075DMS_96KHZ_HR ((int)149600/ 800/2)* 800 +# define MIN_BR_075DMS 21334 /* ceil( 20 * 800 * 100/ 75) */ +# define MAX_BR_075DMS 426667 /* ceil(400 * 800 * 100/ 75) */ +# define MAX_BR_075DMS_NB 152534 /* ceil(143 * 800 * 100/ 75) */ +# define MAX_BR_075DMS_WB 295467 /* ceil(277 * 800 * 100/ 75) */ +# define MAX_BR_075DMS_SSWB 419200 /* ceil(393 * 800 * 100/ 75) */ +#endif +# define CR8_E_TONE_DETECTOR /* Tone detector for hrmode to deactivate TNS - improves SNR and THD+N */ + typedef int32_t LC3_INT32; # if defined(__xtensa__) @@ -76,7 +157,26 @@ typedef int32_t LC3_INT32; # define ALIGNMENT_BALLOC_RED 7 # endif +#ifndef CR8_A_PLC_FADEOUT_TUNING # define PLC2_FADEOUT_IN_MS 30 +#endif + +#ifdef CR8_A_PLC_FADEOUT_TUNING +/* PLC2/PhEcu fading settings */ +/* PLC2/PHEcu muting Table setup settings */ +# define PLC2_FADEOUT_IN_MS_MIN 30 /* Table min */ +# define PLC2_FADEOUT_IN_MS_MAX 140 /* Table max */ +# define PLC2_FADEOUT_RES 10 /* 10 ms steps used in fadeout constant tables */ + +/* current active settings */ +# define PLC2_FADEOUT_IN_MS 30 /* 30 P800 fadeout optimized */ +#if 0 +# define PLC2_FADEOUT_LONG_IN_MS 50 /* 50 ABBA test */ +#endif +# define PLC2_FADEOUT_LONG_IN_MS 120 /* 120 MUSHRA, && stable tonal fadeout optimized */ + +#endif + # define PHECU_FRES 62.5 # define PHECU_C_JACOB 1.1429 # define MAX_LGW 9 /* LGW48K + 1 !! */ @@ -108,16 +208,21 @@ typedef int32_t LC3_INT32; # define TDC_L_FIR_HP 11 # define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ +#ifdef CR9_I_INC_TDC_FADEOUT_LEN +# define PLC_FADEOUT_TYPE_1_IN_MS 200 +#endif # define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */ # define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ # define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ # define PLC34_ATTEN_FAC_100 0.5000 /* attenuation factor for NS and TDC @ 10 ms*/ +#ifdef CR8_G_ADD_75MS +# define PLC34_ATTEN_FAC_075 0.5946 /* attenuation factor for NS and TDC @ 7.5 ms */ +#endif # define PLC34_ATTEN_FAC_050 0.7071 /* attenuation factor for NS and TDC @ 5.0 ms*/ # define PLC34_ATTEN_FAC_025 0.8409 /* attenuation factor for NS and TDC @ 2.5 ms*/ # define FEC_SLOT_BYTES_MIN 40 -# define FEC_SLOT_BYTES_MAX 400 - +# define FEC_SLOT_BYTES_MAX 400 # define LC3_CONST_POW_2_M15 3.051757812500000e-05 # define LC3_CONST_POW_2_23 8388608 @@ -134,16 +239,30 @@ typedef int32_t LC3_INT32; #define G192_ONE 0x0081 #define READ_G192FER /* Allow C executable to also read G192 formatted FER files */ +#ifdef DEBUG +#ifdef READ_G192FER +# define READ_G192_FER_BYTE /* Allow C executable to also read G192 byte formatted FER files 0x20=BAD , 0x21=Good */ +#endif +#endif + + # define LC3_EPS (1.1e-7f) #define M_PI 3.14159265358979323846 /* FUNCTION MACROS */ #define CEILING(x, y) (((x) + (y)-1) / (y)) + + +#ifdef CR8_A_PLC_FADEOUT_TUNING +#define FRAME2FS_IDX_10MS(x) (x<500 ? (x/100) : 5) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4 , 960 -> 5*/ +#define FS2FS_IDX(x) ((x) == 96000 ? 5 : (x) / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4, 96000 -> 5 */ +#else #define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4*/ #define FS2FS_IDX(x) \ (x / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4 \ */ +#endif #define UNUSED(x) (void)(x) /* silence unused parameter warning */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -159,6 +278,7 @@ typedef int32_t LC3_INT32; /* OPTIONS */ +#define MAX_LEN_NR 480 #define MAX_SR 96000 #define EXT_RES_ITER_MAX 20 #define MAX_BW_BANDS_NUMBER 6 diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c index 9392867208e6d9270092e5789153a267c68f13e8..239da4255fcfb10335c7505711c5cdcbf1845296 100644 --- a/lib_lc3plus/detect_cutoff_warped.c +++ b/lib_lc3plus/detect_cutoff_warped.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,10 +13,10 @@ void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) { - const LC3_INT *warp_idx_start = NULL, *warp_idx_stop = NULL; - LC3_INT counter = 0, brickwall = 0, i = 0, stop = 0, dist = 0; - LC3_FLOAT d2_mean = 0, d2_sum = 0, e_diff = 0, thr = 0; - const LC3_INT *bw_dist = NULL; + const LC3_INT *warp_idx_start, *warp_idx_stop; + LC3_INT counter, brickwall = 0, i, stop, dist; + LC3_FLOAT d2_mean, d2_sum, e_diff, thr; + const LC3_INT *bw_dist; warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; @@ -33,6 +33,13 @@ void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_d warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; bw_dist = brickwall_dist; break; +#ifdef CR8_G_ADD_75MS + case 75: + warp_idx_start = BW_warp_idx_start_all_7_5ms[fs_idx - 1]; + warp_idx_stop = BW_warp_idx_stop_all_7_5ms[fs_idx - 1]; + bw_dist = brickwall_dist_7_5ms; + break; +#endif case 100: warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c index a7ff8cd70006ea601d7ffa0b579989a3258ba9f7..23423b5d809734869c165e9fdd62e1fed9ab68ad 100644 --- a/lib_lc3plus/enc_entropy.c +++ b/lib_lc3plus/enc_entropy.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,9 @@ #include "options.h" #include "functions.h" +static const LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; +static const LC3_INT gainLSBbits[4] = {0, 1, 0, 1}; + void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx @@ -18,8 +21,8 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_ ) { LC3_UINT8* ptr; - LC3_INT i = 0, submodeMSB = 0, submodeLSB = 0, tmp = 0, gainMSB = 0, gainLSB = 0; - LC3_INT gainMSBbits[4] = {1, 1, 2, 2}, gainLSBbits[4] = {0, 1, 0, 1}; + LC3_INT i, submodeMSB, submodeLSB, tmp, gainMSB, gainLSB; + LC3_INT16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; @@ -38,7 +41,7 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_ } else { - write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N / 2))); + write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N >> 1))); } /* LSB mode bit */ @@ -100,27 +103,25 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_ void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits) { - LC3_INT k = 0, bit = 0; + LC3_INT k, bit; for (k = 0; k < numbits; k++) { bit = val & 1; write_bit_backward_fl(ptr, bp_side, mask_side, bit); - val = val / 2; + val = val >> 1; } } void write_bit_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT bit) { - if (bit == 0) { - ptr[*bp_side] = ptr[*bp_side] & (255 - *mask_side); - } else { + if (bit != 0) { ptr[*bp_side] = ptr[*bp_side] | *mask_side; - } + } if (*mask_side == 128) { *mask_side = 1; *bp_side = *bp_side - 1; } else { - *mask_side = *mask_side * 2; + *mask_side = *mask_side << 1; } } diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c index c89f7244ca8e03bc7593d0a49ebc873f14981c8c..404b80fb4b10fbb313bbc5d286048728e0bee509 100644 --- a/lib_lc3plus/enc_lc3_fl.c +++ b/lib_lc3plus/enc_lc3_fl.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -62,14 +62,22 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s /* Pitch estimation */ processOlpa_fl(h_EncSetup->s_12k8, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, - &h_EncSetup->olpa_mem_pitch, &T0_out, &normcorr, s_12k8_len, encoder->frame_dms); + &h_EncSetup->olpa_mem_pitch, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + &h_EncSetup->pitch_flag, +#endif + &T0_out, &normcorr, s_12k8_len, encoder->frame_dms); /* LTPF encoder */ process_ltpf_coder_fl(h_EncSetup->s_12k8, s_12k8_len + 1, h_EncSetup->ltpf_enable, T0_out, normcorr, encoder->frame_dms, h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len, &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_ltpf_on, &h_EncSetup->ltpf_mem_pitch, h_EncSetup->ltpf_param, &h_EncSetup->ltpf_mem_mem_normcorr, - <pfBits); + <pfBits +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,encoder->hrmode +#endif +); /* Attack detector */ attack_detector_fl(h_EncSetup->s_in_scaled, encoder->frame_length, encoder->fs, &h_EncSetup->attdec_position, @@ -79,8 +87,12 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s /* Per-band energy */ processPerBandEnergy_fl(encoder->bands_number, encoder->bands_offset, encoder->hrmode, encoder->frame_dms, h_EncSetup->ener, d_fl); /* Near Nyquist detector */ - processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener); - + processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener +#ifdef CR8_E_TONE_DETECTOR + , encoder->frame_dms, encoder->hrmode ); +#else + ); +#endif /* Disable LTPF if nyquist detector triggers or -lfe mode is active*/ if (encoder->near_nyquist_flag != 0 || h_EncSetup->lfe == 1) { @@ -100,8 +112,8 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s BW_cutoff_idx = 0; } - processSnsComputeScf_fl(h_EncSetup->ener, encoder->tilt, encoder->bands_number, h_EncSetup->scf, - h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping); + processSnsComputeScf_fl(h_EncSetup->ener, encoder->bands_number, h_EncSetup->scf, + h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping, encoder->fs_idx); /* SNS Quantizer */ process_snsQuantizesScf_Enc(h_EncSetup->scf, h_EncSetup->L_scf_idx, h_EncSetup->scf_q, h_EncSetup->dct2StructSNS); diff --git a/lib_lc3plus/estimate_global_gain.c b/lib_lc3plus/estimate_global_gain.c index df9b1f5f238f39cfe0c41ae58c398b8746a970df..fdaa977c0644c7d72e4949d298cd2ce835160868 100644 --- a/lib_lc3plus/estimate_global_gain.c +++ b/lib_lc3plus/estimate_global_gain.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -19,9 +19,9 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC ) { - LC3_INT i = 0, N = 0, offset = 0, j = 0, iszero = 0; - LC3_FLOAT g_min = 0, x_max = 0, tmp = 0, ind = 0, ind_min = 0, target = 0, fac = 0, ener = 0; - LC3_FLOAT en[MAX_LEN / 4] = {0}; + LC3_INT i, N, offset, j, iszero, fac; + LC3_FLOAT g_min, x_max, tmp, ind, ind_min, target, ener; + LC3_FLOAT en[MAX_LEN / 4]; LC3_FLOAT reg_val = 4.656612873077393e-10; if (*old_targetBits < 0) { @@ -61,7 +61,7 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC } else { g_min = x_max / (32767 - 0.375); } - /* Prevent positive rounding errors from LC3_LOGTEN function */ + /* Prevent positive rounding errors from LC3_LOG10 function */ ind_min = 28.0 * LC3_LOGTEN(g_min); ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS); @@ -85,8 +85,9 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC fac = 256; offset = 255 + quantizedGainOff; - for (i = 0; i < 8; i++) { - fac = fac * 0.5; + for (i = 0; i < 8; i++) + { + fac = fac >> 1; offset = offset - fac; ener = 0; iszero = 1; diff --git a/lib_lc3plus/fft/cfft.c b/lib_lc3plus/fft/cfft.c index 4bd8d29ade753c2c594dc34d0680fbdb3b9c5e8a..e8a6304ee17ec78ed1fc056c3af0628b6e23b84f 100644 --- a/lib_lc3plus/fft/cfft.c +++ b/lib_lc3plus/fft/cfft.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,6 +8,7 @@ ******************************************************************************/ + #include "options.h" #include "cfft.h" #include "iisfft.h" /* for M_PIl */ diff --git a/lib_lc3plus/fft/cfft.h b/lib_lc3plus/fft/cfft.h index 3902b4c396d152f621d5f61cbfe03c853fabc26e..6ba8dfccd372823a10726793c87d8daa652b90dd 100644 --- a/lib_lc3plus/fft/cfft.h +++ b/lib_lc3plus/fft/cfft.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ +#include "options.h" #include "../functions.h" #ifndef CFFT_H diff --git a/lib_lc3plus/fft/fft_15_16.h b/lib_lc3plus/fft/fft_15_16.h index 83ca77353b5c83df31ef3bd2c278a251ab5d4240..c527f1bf5625413c85da3c5f7026f8ed71f66ea2 100644 --- a/lib_lc3plus/fft/fft_15_16.h +++ b/lib_lc3plus/fft/fft_15_16.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_240_480.h b/lib_lc3plus/fft/fft_240_480.h index c1d96c87b8016d516ff5cd96687309a11f450cd9..18a0c8707a871b091ff60d0f59262e500d89ff9f 100644 --- a/lib_lc3plus/fft/fft_240_480.h +++ b/lib_lc3plus/fft/fft_240_480.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_2_9.h b/lib_lc3plus/fft/fft_2_9.h index 54f4f839dfcba878cdf037f9940d49982c58c3c0..55fe84f3b779057b5c65c63587b262cf20b7cf15 100644 --- a/lib_lc3plus/fft/fft_2_9.h +++ b/lib_lc3plus/fft/fft_2_9.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_32.h b/lib_lc3plus/fft/fft_32.h index 48b891108b88b53a9529c32d035b1aba981c4968..803923a0158c42dc3f0d88ae81cb5765e6acf8a5 100644 --- a/lib_lc3plus/fft/fft_32.h +++ b/lib_lc3plus/fft/fft_32.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_384_768.h b/lib_lc3plus/fft/fft_384_768.h index 47f42e90d6546a945a4857a14a43bbc90ec2cfe9..bd89393c174c8f14b4b2db5fee253f0a41e803c8 100644 --- a/lib_lc3plus/fft/fft_384_768.h +++ b/lib_lc3plus/fft/fft_384_768.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_60_128.h b/lib_lc3plus/fft/fft_60_128.h index 75f1aaef45cf21c69b717e39a63cdff31f2c984b..e5a88ccad873d19fb1757cc14df1be36d6502b50 100644 --- a/lib_lc3plus/fft/fft_60_128.h +++ b/lib_lc3plus/fft/fft_60_128.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_generic.h b/lib_lc3plus/fft/fft_generic.h index e517ffb2501daf1d5e4ff16fcb1bb9197d6a616e..903875ab5a7b6ef471e4898ca3a868d49bebeb67 100644 --- a/lib_lc3plus/fft/fft_generic.h +++ b/lib_lc3plus/fft/fft_generic.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/iis_fft.c b/lib_lc3plus/fft/iis_fft.c index b1f8ab5ab8d42629700fa31642587bb93f4900e5..30ae240200b48660d57df9a92d490f301551c2ab 100644 --- a/lib_lc3plus/fft/iis_fft.c +++ b/lib_lc3plus/fft/iis_fft.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -15,8 +15,8 @@ #include #include #include - #include "iis_fft.h" + /**************************************************************************************************/ /* AFFT uses two fft implementations @@ -25,7 +25,6 @@ fast lengths, check the fft_n function. */ - #define FFT_COMPLEX 1 #define FFT_REAL 2 diff --git a/lib_lc3plus/fft/iis_fft.h b/lib_lc3plus/fft/iis_fft.h index b658930fa7cf51fae7861d9a1dca2c46671e7fdb..b70a3719d3d671c8e47f4191955fbe78ae8076a0 100644 --- a/lib_lc3plus/fft/iis_fft.h +++ b/lib_lc3plus/fft/iis_fft.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef IIS_FFT_H #define IIS_FFT_H +#include "options.h" #include "../structs.h" #include "../defines.h" #include "cfft.h" diff --git a/lib_lc3plus/fft/iisfft.c b/lib_lc3plus/fft/iisfft.c index 227d2b6037c8fef97141631b512e6736987603b9..cdf7f8d2a8faf2d494a4693eba9cbc0682fb786f 100644 --- a/lib_lc3plus/fft/iisfft.c +++ b/lib_lc3plus/fft/iisfft.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,8 +8,8 @@ ******************************************************************************/ -#include "options.h" +#include "options.h" #include #include /* for mmove */ #include diff --git a/lib_lc3plus/fft/iisfft.h b/lib_lc3plus/fft/iisfft.h index 7b448e2bbeca4f093791f039e885c42c94688af2..b45e73cdec772d0f494ba1d45c79b75cf2e1e82b 100644 --- a/lib_lc3plus/fft/iisfft.h +++ b/lib_lc3plus/fft/iisfft.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef IISFFT_H #define IISFFT_H +#include "options.h" #include "../defines.h" #ifndef M_PIl diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h index 7a529a25d7acbe5e90b00b6d72f5199fa2f0ae47..b0997e85fac8d5e7973c498885bfab736bead53c 100644 --- a/lib_lc3plus/functions.h +++ b/lib_lc3plus/functions.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef FUNCTIONS_H #define FUNCTIONS_H +#include "options.h" #include "clib.h" #include "defines.h" #include "float.h" @@ -106,8 +107,11 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3 void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx); -void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, LC3_INT* T0_out, - LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms); +void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + LC3_INT* pitch_flag, +#endif + LC3_INT* T0_out,LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms); void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out @@ -117,14 +121,18 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs); -void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor); +void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx); void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_LC3_INT); void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx); void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener); - + const LC3_INT bands_number, const LC3_FLOAT* ener +#ifdef CR8_E_TONE_DETECTOR + , const LC3_INT16 frame_dms, const LC3_INT16 hrmode ); +#else + ); +#endif void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d); void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, @@ -134,12 +142,19 @@ void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, - LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits); + LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,LC3_INT16 hrmode +#endif +); void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, LC3_INT* mem_pitch_LC3_INT, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping , LC3_INT *mem_ltpf_active +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms +#endif ); void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], @@ -225,10 +240,19 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, - LC3_FLOAT *cum_fflcAtten); + LC3_FLOAT *cum_fflcAtten +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ); + void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, - LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx); + LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ); void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len, LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); @@ -253,7 +277,12 @@ void plc_phEcu_spec_ana(LC3_FLOAT* xfp, LC3_INT32 xfp_len, const LC3_FLOAT* LC3_FLOAT* f0hzLtpBinPtr, LC3_FLOAT* f0gainLtpPtr, LC3_INT32 bw_idx, Fft* PhEcu_Fft); void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, - LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, LC3_FLOAT *corr_phase_dbg, + LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT16 fadeout, /* needed for DC muting */ + LC3_INT16* nonpure_tone_flag_ptr, /* i/o: flag */ +#endif + LC3_FLOAT *corr_phase_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg); void plc_phEcu_rec_frame(Complex *X_in, LC3_INT32 xfp_len, LC3_INT32 Lecu, const LC3_FLOAT *whr, const LC3_FLOAT *winMDCT, LC3_INT32 Lprot, LC3_FLOAT *xfp, LC3_INT32 time_offs, LC3_FLOAT *x_out, @@ -268,12 +297,21 @@ void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FL void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change, LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, - LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames, LC3_FLOAT *thresh_dbg); + LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames, + LC3_FLOAT *thresh_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ); void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, - LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg); + LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ); void plc_phEcu_hq_ecu( LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, LC3_FLOAT *xfp, LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, @@ -287,6 +325,10 @@ void plc_phEcu_hq_ecu( LC3_FLOAT *st_beta_mute, LC3_FLOAT *st_mag_chg_1st, LC3_FLOAT *st_Xavg, LC3_INT32 LA_ZEROS, LC3_FLOAT *x_tda, LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, LC3_FLOAT *corr_phase_dbg ,Fft* PhEcu_Fft,Fft* PhEcu_Ifft +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type, + LC3_INT16 *nonpure_tone_flag_ptr +#endif ); void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands); @@ -296,7 +338,11 @@ void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, void processTdcApply_fl(const LC3_INT32 pitch_LC3_INT, const LC3_FLOAT *preemphFac, const LC3_FLOAT* A, const LC3_INT32 lpc_order, const LC3_FLOAT* pcmbufHist, const LC3_INT32 max_len_pcm_plc, const LC3_INT32 N, const LC3_INT32 frame_dms, const LC3_INT32 SampRate, const LC3_INT32 nbLostCmpt, const LC3_INT32 overlap, const LC3_FLOAT *stabFac, LC3_FLOAT harmonicBuf[MAX_PITCH], LC3_FLOAT synthHist[M], - LC3_INT32* fract, LC3_INT16* seed, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth); + LC3_INT32* fract, LC3_INT16* seed, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,LC3_UINT8 plc_fadeout_type +#endif +); void* balloc(void* base, size_t* base_size, size_t size); diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c index 5d38aa6cc78077272ea68a12eb0bcf05a5d714ee..b1b5d4b43b9ac9b54d48834fbb5c4cece45f9727 100644 --- a/lib_lc3plus/imdct.c +++ b/lib_lc3plus/imdct.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -14,8 +14,8 @@ /* Function expects already flipped window */ void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, Dct4* dct) { - LC3_FLOAT x_tda[MAX_LEN] = {0}, x_ov[2 * MAX_LEN] = {0}; - LC3_INT i = 0, j = 0; + LC3_FLOAT x_tda[MAX_LEN], x_ov[2 * MAX_LEN]; + LC3_INT i, j; /* Flip imdct window up to down */ i = winLen - 1; @@ -61,7 +61,7 @@ void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_IN void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT* win, LC3_INT32 winLen, LC3_INT32 last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x) { - LC3_FLOAT x_ov[2 * MAX_LEN] = {0}; + LC3_FLOAT x_ov[2 * MAX_LEN]; LC3_INT32 i, j; move_float(x_ov, &x_tda[yLen / 2], yLen / 2); diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c index 17d2ccb71296628426a4edbb9598145b700ecf1f..f09c53a5386fbf839d505a10bc0015d714734101 100644 --- a/lib_lc3plus/lc3.c +++ b/lib_lc3plus/lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -71,6 +71,9 @@ static int lc3plus_frame_size_supported(float frame_ms) { case 25: /* fallthru */ case 50: /* fallthru */ +#ifdef CR8_G_ADD_75MS + case 75: /* fallthru */ +#endif case 100: return 1; default: break; } @@ -102,7 +105,6 @@ int32_t lc3_enc_supported_lfe(void) LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]) { int ch = 0; - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR); RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); @@ -198,7 +200,6 @@ LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms) LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) { LC3_INT effective_fs; - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); #ifdef ENABLE_HR_MODE_FL_FLAG RETURN_IF(encoder->hrmode == 1, LC3PLUS_HRMODE_BW_ERROR); @@ -359,7 +360,7 @@ LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) { - int ch = 0; + int ch = 0; RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); for (ch = 0; ch < decoder->channels; ch++) { @@ -388,7 +389,6 @@ LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmod { LC3PLUS_EpMode oldEpmode; LC3PLUS_Error error; - RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); oldEpmode = encoder->epmode; diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h index 3e45438fede66c23bfeb2efc0b3927e7a46e78d0..0981cea84b9ee01072eb44c7c4ab01e7d11af2be 100644 --- a/lib_lc3plus/lc3.h +++ b/lib_lc3plus/lc3.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -25,6 +25,7 @@ #define LC3PLUS_H #ifndef _MSC_VER +#include "options.h" #include #else typedef unsigned char uint8_t; @@ -36,7 +37,7 @@ typedef __int32 int32_t; #define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro)) /*! Version number to ensure header and binary are matching. */ -#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 6, 9) +#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 2) /*! Maximum number of supported channels. The actual binary might support * less, use lc3plus_channels_supported() to check. */ diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c index 14f443f860d995f76b063ecbbe8636f54b52720f..f1fc8fe714590f7565ef85e735ca5070dadcb9e7 100644 --- a/lib_lc3plus/lc3plus_fft.c +++ b/lib_lc3plus/lc3plus_fft.c @@ -1,12 +1,12 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - + #include "options.h" #include "functions.h" @@ -19,11 +19,11 @@ void fft_init(Fft* fft, int length) HANDLE_IIS_FFT handle = NULL; IIS_FFT_ERROR error = 0; assert(length % 2 == 0); - + fft->length = length; - + error = LC3_IIS_CFFT_Create(&handle, length, IIS_FFT_FWD); - + assert(error == IIS_FFT_NO_ERROR); fft->handle = handle; } @@ -31,10 +31,10 @@ void fft_init(Fft* fft, int length) void fft_free(Fft* fft) { IIS_FFT_ERROR error = 0; - + if (fft) { error = LC3_IIS_CFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); - + assert(error == IIS_FFT_NO_ERROR); memset(fft, 0, sizeof(*fft)); } @@ -82,7 +82,7 @@ void fft_apply(Fft* fft, const Complex* input, Complex* output) { IIS_FFT_ERROR error = 0; error = LC3_IIS_FFT_Apply_CFFT(fft->handle, input, output); - + assert(error == IIS_FFT_NO_ERROR); } @@ -90,10 +90,11 @@ void fft_apply(Fft* fft, const Complex* input, Complex* output) void real_fft_apply(Fft* fft, const LC3_FLOAT* input, LC3_FLOAT* output) { IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; - + UNUSED(error); - error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); + error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); assert(error == IIS_FFT_NO_ERROR); } + diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h index d9d6c89675d4fadc0455effff0f0edae8fc2193c..266f91a1656a6ff187e3c2f0cf1b3c39c9274ffc 100644 --- a/lib_lc3plus/license.h +++ b/lib_lc3plus/license.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,11 +8,12 @@ ******************************************************************************/ +#include "options.h" #include "defines.h" static const char *const LICENSE = "*******************************************************************************\n" - "* ETSI TS 103 634 V1.4.1 *\n" + "* ETSI TS 103 634 V1.4.3 *\n" "* Low Complexity Communication Codec Plus (LC3plus) *\n" "* Floating Point Software V%i.%i.%iETSI, " __DATE__ " *\n" "* Copyright licence is solely granted through ETSI Intellectual Property *\n" diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c index fac8c481c003aee4bf8fb8b2d03b921cd33a047f..286d8fa166bd26e29c3a09c1f3b2d610ad599526 100644 --- a/lib_lc3plus/ltpf_coder.c +++ b/lib_lc3plus/ltpf_coder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -15,7 +15,7 @@ static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) { - LC3_INT max_i = 0, i = 0; + LC3_INT max_i = 0, i; LC3_FLOAT max = 0; if (len <= 0) { @@ -34,16 +34,29 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, - LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits) + LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits +#ifdef CR9_K_REDUCE_NORM_CORR_TH + , LC3_INT16 hrmode +#endif +) { - LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)] = {0}, sum = 0, buf_tmp[MAX_LEN] = {0}, cor_up[MAX_LEN] = {0}, *x; - LC3_INT i = 0, j = 0, k = 0, n = 0, step = 0, N = 0, ltpf_active = 0, pitch_search_delta = 0, + LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)], sum = 0, cor_up[(MAX_PITCH_12K8 - MIN_PITCH_12K8) / 2] = {0}, *x; + LC3_INT i, j, n, step, N, ltpf_active, pitch_search_delta, pitch_search_upsamp = 0, pitch_search_L_interpol1 = 0, t0_min = 0, t0_max = 0, t_min = 0, t_max = 0, temp2 = 0, t1 = 0, pitch_int = 0, pitch_fr = 0, midpoint = 0, delta_up = 0, delta_down = 0, pitch_index = 0, gain = 0, acflen = 0; - LC3_FLOAT norm_corr = 0, cor[MAX_LEN] = {0}, cor_int[MAX_LEN] = {0}, currFrame[MAX_LEN] = {0}, predFrame[MAX_LEN] = {0}, sum1 = 0, sum2 = 0, sum3 = 0; + LC3_FLOAT cor_tmp, cor_int_tmp, norm_corr = 0, cor[MAX_LEN_NR], cor_int[MAX_LEN_NR], sum1 = 0, sum2 = 0, sum3 = 0; LC3_FLOAT pitch = 0; +#ifdef CR9_K_REDUCE_NORM_CORR_TH + LC3_FLOAT normCorrTh = 0.0f; + if (hrmode) { + normCorrTh = 0.4; + } else { + normCorrTh = 0.6; + } +#endif + /* Signal Buffer */ N = xLen - 1; x = &buffer[memLen]; @@ -59,7 +72,11 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC pitch_search_upsamp = 4; pitch_search_L_interpol1 = 4; +#ifdef CR9_K_REDUCE_NORM_CORR_TH + if (pitch_ol_norm_corr > normCorrTh) { +#else if (pitch_ol_norm_corr > 0.6) { +#endif /* Search Bounds */ t0_min = pitch_ol - pitch_search_delta; t0_max = pitch_ol + pitch_search_delta; @@ -83,19 +100,24 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC sum1 += x[j] * x[j]; sum2 += x[j - t_min] * x[j - t_min]; } + + /* Do first iteration outside of loop */ + sum = mac_loop(x, &x[-t_min], acflen); + + sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05; + norm_corr = sum / sum3; + + norm_corr = MAX(0, norm_corr); + cor[0] = norm_corr; /* Compute Cross-Correlation */ - for (i = t_min; i <= t_max; i++) { - sum = 0; - for (j = 0; j < acflen; j++) { - sum += x[j] * x[j - i]; - } + for (i = t_min + 1; i <= t_max; i++) { + sum = mac_loop(x, &x[-i], acflen); - if (i > t_min) { - sum2 = sum2 + x[-i]*x[-i] + sum2 = sum2 + x[-i]*x[-i] - x[acflen - 1 - ( i - 1 )]*x[acflen - 1 - ( i - 1 )]; - } - sum3 = LC3_SQRT(sum1 * sum2) + LC3_POW(10, -5); + + sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05; norm_corr = sum / sum3; norm_corr = MAX(0, norm_corr); @@ -104,13 +126,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC } /* Find Integer Pitch-Lag */ - j = 0; - for (i = pitch_search_L_interpol1; i <= t_max - t_min - pitch_search_L_interpol1; i++) { - buf_tmp[j] = cor[i]; - j++; - } - - temp2 = searchMaxIndice(buf_tmp, j); + temp2 = searchMaxIndice(&cor[pitch_search_L_interpol1], t_max - t_min - pitch_search_L_interpol1 - pitch_search_L_interpol1 + 1); t1 = temp2 + t0_min; assert(t1 >= t0_min && t1 <= t0_max); @@ -128,13 +144,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC } for (i = 0; i < pitch_search_upsamp * (t0_max - t0_min + 1); i++) { - sum = 0; - - k = 0; - for (j = i; j < i + 32; j++) { - sum += cor_up[j] * inter4_1[k]; - k++; - } + sum = mac_loop(&cor_up[i], (const LC3_FLOAT *)inter4_1, 32); cor_int[i] = sum; } @@ -153,14 +163,15 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC } else { delta_down = pitch_search_upsamp - step; } - + j = 0; for (i = midpoint - delta_down - 1; i <= midpoint + delta_up; i = i + step) { - buf_tmp[j] = cor_int[i]; + cor[j] = cor_int[i]; j++; } - temp2 = searchMaxIndice(buf_tmp, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1); + + temp2 = searchMaxIndice(cor, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1); pitch_fr = temp2 * step - delta_down; if (pitch_fr >= 0) { @@ -188,34 +199,25 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC pitch = (LC3_FLOAT) pitch_int + (LC3_FLOAT) pitch_fr / 4.0; + /* Normalized Correlation */ + sum1 = sum2 = sum3 = 0; for (n = 0; n < acflen; n++) { - currFrame[n] = x[n + 1] * enc_inter_filter[0][0] + + cor_tmp = x[n + 1] * enc_inter_filter[0][0] + x[n] * enc_inter_filter[0][1] + x[n - 1] * enc_inter_filter[0][2]; - predFrame[n] = x[n - pitch_int + 1] * enc_inter_filter[pitch_fr][0] + + cor_int_tmp = x[n - pitch_int + 1] * enc_inter_filter[pitch_fr][0] + x[n - pitch_int] * enc_inter_filter[pitch_fr][1] + x[n - pitch_int - 1] * enc_inter_filter[pitch_fr][2] + x[n - pitch_int - 2] * enc_inter_filter[pitch_fr][3]; + + sum1 += cor_tmp * cor_int_tmp; + sum2 += cor_tmp * cor_tmp; + sum3 += cor_int_tmp * cor_int_tmp; } - /* Normalized Correlation */ - sum1 = sum2 = sum3 = 0; - - for (i = 0; i < acflen; i++) { - sum1 += currFrame[i] * predFrame[i]; - } - - for (i = 0; i < acflen; i++) { - sum2 += currFrame[i] * currFrame[i]; - } - - for (i = 0; i < acflen; i++) { - sum3 += predFrame[i] * predFrame[i]; - } - - sum2 = LC3_SQRT(sum2 * sum3) + LC3_POW(10, -5); + sum2 = LC3_SQRT(sum2 * sum3) + 1.00e-05; norm_corr = sum1 / sum2; assert(norm_corr >= -1.00001 && norm_corr <= 1.00001); diff --git a/lib_lc3plus/ltpf_decoder.c b/lib_lc3plus/ltpf_decoder.c index a40c85213a13afa678bd1e4cbff6a62b5169086a..e95a274a46907cbb213f16c8f81006f86e1113ef 100644 --- a/lib_lc3plus/ltpf_decoder.c +++ b/lib_lc3plus/ltpf_decoder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -16,18 +16,31 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping , LC3_INT *mem_ltpf_active +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + , LC3_FLOAT *rel_pitch_change, LC3_INT hrmode, LC3_INT frame_dms +#endif ) { - LC3_INT i = 0, j = 0, n = 0, N = 0, L_past_x = 0, N4 = 0, N34 = 0, - pitch_int = 0, pitch_fr = 0, p1 = 0, p2 = 0, L_past_y = 0, inter_len = 0, tilt_len = 0, - tilt_len_r = 0, inter_len_r = 0, old_x_len = 0, old_y_len = 0; - - LC3_FLOAT conf_alpha = 0, gain = 0, a1[MAX_LEN] = {0}, a2[MAX_LEN] = {0}, b1[MAX_LEN] = {0}, b2[MAX_LEN] = {0}, - buf_x[4 * MAX_LEN] = {0}, buf_y[4 * MAX_LEN] = {0}, buf_z[4 * MAX_LEN] = {0}, pitch = 0, sum1 = 0, sum2 = 0; - + LC3_INT i, j, n, N, L_past_x, N4, N34, + pitch_int, pitch_fr, p1, p2, L_past_y, inter_len, tilt_len = 0, + tilt_len_r, inter_len_r, old_x_len, old_y_len; + + LC3_FLOAT conf_alpha, gain, a1[12], a2[12], b1[11], b2[11], + buf_x[4 * MAX_LEN], buf_y[4 * MAX_LEN], buf_z[4 * MAX_LEN], pitch, sum1, sum2; +#ifdef CR9_LTPF_REWRITE + LC3_FLOAT *p_x, *p_y, *p_y2, *p_x_init, *p_y_init, *p_a1, *p_b1, *p_a2, *p_b2, fade_fac, current_fade_fac_up, current_fade_fac_down; +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + LC3_FLOAT pitch_fl_c_old, pitch_delta; +#endif const LC3_FLOAT *inter_filter[4], *tilt_filter[4]; - +#ifdef WMOPS + push_wmops("process_ltpf_decoder_fl"); +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + pitch_fl_c_old = (LC3_FLOAT) *mem_pitch_int + (LC3_FLOAT)*mem_pitch_fr / 4.0; +#endif conf_alpha = 0.85; if (bfi != 1) { @@ -213,6 +226,13 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f } /* First quarter of the current frame: cross-fading */ +#ifdef CR9_LTPF_REWRITE + fade_fac = 1. / (LC3_FLOAT) N4; + current_fade_fac_up = 0.f; + current_fade_fac_down = 1.f; + (void) p_x; (void) p_y; (void) p_a1; (void) p_b1; +#endif + if (mem_param[1] == 0 && param[1] == 0) { memmove(&buf_y[L_past_y], &buf_x[L_past_x], sizeof(LC3_FLOAT) * N4); @@ -232,8 +252,14 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f j++; } +#ifdef CR9_LTPF_REWRITE + buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_down * sum1 + + current_fade_fac_down * sum2; + current_fade_fac_down -= fade_fac; +#else buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; +#endif } } else if (mem_param[1] == 0 && param[1] == 1) { @@ -252,7 +278,12 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f j++; } +#ifdef CR9_LTPF_REWRITE + buf_y[L_past_y + n] = buf_x[L_past_x + n] - current_fade_fac_up * sum1 + current_fade_fac_up * sum2; + current_fade_fac_up += fade_fac; +#else buf_y[L_past_y + n] = buf_x[L_past_x + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; +#endif } } else if (*mem_pitch_int == pitch_int && *mem_pitch_fr == pitch_fr) { for (n = 0; n < N4; n++) { @@ -273,6 +304,69 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f buf_y[L_past_y + n] = buf_x[L_past_x + n] - sum1 + sum2; } } else { +#ifdef CR9_LTPF_REWRITE + p_x_init = &buf_x[L_past_x]; + p_y_init = &buf_y[L_past_y - p1 + inter_len - 1]; + p_y2 = &buf_y[L_past_y]; + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + p_b1 = b1; + p_x = p_x_init; + for (i = tilt_len; i >= 0; i--) { + sum1 += *p_b1 * *p_x; + p_b1++; + p_x--; + } + + p_y = p_y_init; + p_a1 = a1; + for (i = 2*inter_len - 1; i >= 0; i--) { + sum2 += *p_a1 * *p_y; + p_a1++; + p_y--; + } + + *p_y2 = *p_x_init - current_fade_fac_down * sum1 + + current_fade_fac_down * sum2; + current_fade_fac_down -= fade_fac; + p_x_init++; + p_y_init++; + p_y2++; + } + + move_float(buf_z, buf_y, (old_y_len + xLen)); + p_x_init = &buf_z[L_past_y]; /* buf z in this case */ + p_y_init = &buf_y[L_past_y - p2 + inter_len - 1]; + p_y2 = &buf_y[L_past_y]; + + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + p_x = p_x_init; + p_b2 = b2; + for (i = tilt_len; i >= 0; i--) { + sum1 += *p_b2 * *p_x; + p_b2++; + p_x--; + } + + p_y = p_y_init; + p_a2 = a2; + for (i = 2*inter_len - 1; i >= 0; i--) { + sum2 += *p_a2 * *p_y; + p_a2++; + p_y--; + } + + *p_y2 = *p_x_init - current_fade_fac_up * sum1 + current_fade_fac_up * sum2; + current_fade_fac_up += fade_fac; + p_x_init++; + p_y_init++; + p_y2++; + } +#else for (n = 0; n < N4; n++) { sum1 = 0; sum2 = 0; @@ -292,7 +386,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; } - memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * 4 * MAX_LEN); + memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * (old_y_len + xLen)); for (n = 0; n < N4; n++) { sum1 = 0; @@ -311,8 +405,45 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f buf_y[L_past_y + n] = buf_z[L_past_y + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; } +#endif } +#ifdef CR9_LTPF_REWRITE + /* Second quarter of the current frame */ + if (param[1] == 0) { + move_float(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], + ((L_past_x + N4 + N34) - (L_past_x + N4))); + } else { + p_x_init = &buf_x[L_past_x + N4]; + p_y_init = &buf_y[L_past_y + N4 - p2 + inter_len - 1]; + p_y2 = &buf_y[L_past_y + N4]; + for (n = 0; n < N34; n++) { + sum1 = 0; + sum2 = 0; + p_b2 = b2; + p_x = p_x_init; + + for (i = 0; i <= tilt_len; i++) { + sum1 += *p_b2 * *p_x; + p_b2++; + p_x--; + } + + p_a2 = a2; + p_y = p_y_init; + + for (i = 2*inter_len - 1; i >= 0; i--) { + sum2 += *p_a2 * *p_y; + p_a2++; + p_y--; + } + p_y_init++; + *p_y2 = *p_x_init - sum1 + sum2; + p_x_init++; + p_y2++; + } + } +#else /* Second quarter of the current frame */ if (param[1] == 0) { memmove(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], @@ -336,7 +467,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f buf_y[L_past_y + N4 + n] = buf_x[L_past_x + N4 + n] - sum1 + sum2; } } - +#endif /* Output */ move_float(y, &buf_y[L_past_y], N); @@ -353,4 +484,14 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f *mem_pitch_fr = pitch_fr; *mem_gain = gain; *mem_beta_idx = conf_beta_idx; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + if (bfi == 0 && hrmode == 1 && (frame_dms == 50 || frame_dms == 25)){ + pitch_delta = LC3_FABS(pitch_fl_c_old - (LC3_FLOAT)pitch_int - (LC3_FLOAT)(pitch_fr / 4.0)); + *rel_pitch_change = pitch_delta / MAX(pitch_fl_c_old, 1); + } +#endif + +#ifdef WMOPS + pop_wmops(); +#endif } diff --git a/lib_lc3plus/mdct.c b/lib_lc3plus/mdct.c index 11618b9465d4e3303f4251a50142f1f3b2954f31..ff4075977d1703dd8bfe1a6b834510b358eee3c0 100644 --- a/lib_lc3plus/mdct.c +++ b/lib_lc3plus/mdct.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -31,6 +31,26 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h return NULL; } } +#ifdef CR8_G_ADD_75MS + else if (frame_dms == 75) { + switch (length) { + case 60: + return MDCT_WINS_7_5ms[hrmode][0]; + case 120: + return MDCT_WINS_7_5ms[hrmode][1]; + case 180: + return MDCT_WINS_7_5ms[hrmode][2]; + case 240: + return MDCT_WINS_7_5ms[hrmode][3]; + case 360: + return MDCT_WINS_7_5ms[hrmode][4]; + case 720: + return MDCT_WINS_7_5ms[hrmode][5]; + default: + return NULL; + } + } +#endif else if (frame_dms == 50) { switch (length) { case 40: @@ -74,10 +94,15 @@ void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC { if (frame_dms == 100) { mdct->leading_zeros = MDCT_la_zeroes[fs_idx]; - } + } +#ifdef CR8_G_ADD_75MS + else if (frame_dms == 75) { + mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx]; + } +#endif else if (frame_dms == 50) { mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx]; - } + } else if (frame_dms == 25) { mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx]; } @@ -103,8 +128,8 @@ void mdct_free(Mdct* mdct) void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) { - LC3_FLOAT tmp[MAX_LEN * 2] = {0}; - LC3_INT i = 0; + LC3_FLOAT tmp[MAX_LEN * 2]; + LC3_INT i; LC3_INT hlen; move_float(tmp, mdct->mem, mdct->mem_length); diff --git a/lib_lc3plus/mdct_shaping.c b/lib_lc3plus/mdct_shaping.c index 18761925042015e48be9b8e9f9bbb2ea46a0e376..d3ca7dd953b35d25cbbb96b8526b89d5d2402671 100644 --- a/lib_lc3plus/mdct_shaping.c +++ b/lib_lc3plus/mdct_shaping.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,11 +13,15 @@ void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) { - LC3_INT i = 0, j = 0; + LC3_INT i, j; + LC3_FLOAT val; + j = 0; for (i = 0; i < fdns_npts; i++) { + val = scf[i]; + for (; j < bands_offset[i + 1]; j++) { - x[j] = x[j] * scf[i]; + x[j] = x[j] * val; } } } diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c index ce94351302bcce089ac5c764420ae8fb4487cff2..e18eb52112d376c2b8be7034164b25edacc10df2 100644 --- a/lib_lc3plus/near_nyquist_detector.c +++ b/lib_lc3plus/near_nyquist_detector.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -7,32 +7,86 @@ * estoppel or otherwise. * ******************************************************************************/ -#include "functions.h" #include "options.h" +#include "functions.h" void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, - const LC3_INT bands_number, const LC3_FLOAT* ener) + const LC3_INT bands_number, const LC3_FLOAT* ener +#ifdef CR8_E_TONE_DETECTOR + , const LC3_INT16 frame_dms, const LC3_INT16 hrmode) +#else +) +#endif { *near_nyquist_flag = 0; +#ifdef CR8_E_TONE_DETECTOR + if (hrmode == 0){ +#endif + if (fs_idx < 4) + { + LC3_INT i = 0; + LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; + + for (i=0; i NN_thresh * ener_low){ + *near_nyquist_flag = 1; + } + } +#ifdef CR8_E_TONE_DETECTOR + } + else // hrmode == 1 { - LC3_INT i = 0; - LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; + // inverse spectral flatness = mean(energy) ./ 2^(mean(log2(energy))); + LC3_INT32 td_thresh, i = 0; + LC3_FLOAT mean_ener = 0, mean_ener_log2 = 0, inv_flatness = 0; - for (i=0; i NN_thresh * ener_low){ - *near_nyquist_flag = 1; + // calculate geometric mean + for (i = 0; i < bands_number; i++) + { + if (ener[i] != 0) { + mean_ener_log2 += LC3_LOGTWO(ener[i]); + } } + mean_ener_log2 = mean_ener_log2 / bands_number; + + inv_flatness = mean_ener / LC3_POW(2,mean_ener_log2); + + if (inv_flatness > td_thresh) { + *near_nyquist_flag = 1; + } } +#endif // CR8_E_TONE_DETECTOR } diff --git a/lib_lc3plus/noise_factor.c b/lib_lc3plus/noise_factor.c index c5aa582e456812b02a60d7a27d3ad935e55fb210..9cf130348f74dafed4f62698fa48a62ab1e71a2c 100644 --- a/lib_lc3plus/noise_factor.c +++ b/lib_lc3plus/noise_factor.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -15,94 +15,111 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3 LC3_INT target_bytes ) { - LC3_INT sumZeroLines = 0, kZeroLines = 0, startOffset = 0, nTransWidth = 0, end = 0, start = 0, i = 0, j = 0, k = 0, - allZeros = 0, m = 0; - LC3_FLOAT fac_ns_unq = 0, mean = 0, idx = 0, nsf1 = 0, nsf2 = 0; - LC3_INT zeroLines[MAX_LEN] = {0}, zL1[MAX_LEN] = {0}, zL2[MAX_LEN] = {0}; + LC3_INT sumZeroLines = 0, kZeroLines = 0, startOffset = 0, nTransWidth = 0, i = 0, j = 0, k = 0, m = 0, nzeros = 0; + LC3_FLOAT fac_ns_unq = 0, idx = 0, nsf1 = 0, nsf2 = 0; + LC3_INT zeroLines[MAX_LEN]; switch (frame_dms) { case 25: - nTransWidth = 4; + nTransWidth = 1; startOffset = 6; break; case 50: - nTransWidth = 4; + nTransWidth = 1; startOffset = 12; break; +#ifdef CR8_G_ADD_75MS + case 75: + nTransWidth = 2; + startOffset = 18; + break; +#endif case 100: - nTransWidth = 8; + nTransWidth = 3; startOffset = 24; break; } - for (k = startOffset; k < BW_cutoff_idx; k++) { - allZeros = 1; - - start = k - (nTransWidth - 2) / 2; - end = MIN(BW_cutoff_idx - 1, k + (nTransWidth - 2) / 2); - - for (i = start; i <= end; i++) { - if (xq[i] != 0) { - allZeros = 0; - } + for (k = startOffset - nTransWidth; k < startOffset + nTransWidth; k++) + { + if (xq[k] != 0) + { + nzeros = -2 * nTransWidth - 1; + } + if (xq[k] == 0) + { + nzeros ++; + } + } + for (k = startOffset; k < BW_cutoff_idx - nTransWidth; k++) + { + if (xq[k + nTransWidth] != 0) + { + nzeros = -2 * nTransWidth - 1; } + if (xq[k + nTransWidth] == 0) + { + nzeros ++; + } + if (nzeros >= 0) + { + zeroLines[j++] = k; + } + } - if (allZeros == 1) { - zeroLines[j] = k + 1; - kZeroLines++; - j++; + for (k = BW_cutoff_idx - nTransWidth; k < BW_cutoff_idx; k++) + { + nzeros ++; + if (nzeros >= 0) + { + zeroLines[j++] = k; } } - for (i = 0; i < kZeroLines; i++) { - sumZeroLines += zeroLines[i]; + if (j == 0) { + fac_ns_unq = 0; } + else + { + kZeroLines = j; - if (sumZeroLines > 0) { + fac_ns_unq = 0; for (j = 0; j < kZeroLines; j++) { - mean += LC3_FABS(x[zeroLines[j] - 1]); + fac_ns_unq += LC3_FABS(x[zeroLines[j]]); } - fac_ns_unq = mean / (gg * kZeroLines); - } else { - fac_ns_unq = 0; - } + fac_ns_unq /= (gg) * kZeroLines; + + + + if (kZeroLines > 1 && target_bytes <= 20 && frame_dms == 100) { + + j = 0, k = 0, nsf1 = 0, nsf2 = 0, sumZeroLines = 0; + + for (i = 0; i < kZeroLines; i++) { + sumZeroLines += zeroLines[i]; + } - if (kZeroLines > 0) - { - if (target_bytes <= 20 && frame_dms == 100) { - j = 0, k = 0; m = floor(sumZeroLines / kZeroLines); for (i = 0; i < kZeroLines; i++) { if (zeroLines[i] <= m) { - zL1[j] = zeroLines[i]; j++; + nsf1 += LC3_FABS(x[zeroLines[i]]); } - - if (zeroLines[i] > m) { - zL2[k] = zeroLines[i]; + else { + nsf2 += LC3_FABS(x[zeroLines[i]]); k++; } } - mean = 0; - for (i = 0; i < j; i++) { - mean += LC3_FABS(x[zL1[i] - 1]) / gg; - } - - nsf1 = mean / j; - - mean = 0; - for (i = 0; i < k; i++) { - mean += LC3_FABS(x[zL2[i] - 1]) / gg; - } - - nsf2 = mean / k; + nsf1 /= (gg) * j; + nsf2 /= (gg) * k; fac_ns_unq = MIN(nsf1, nsf2); } + } idx = round(8 - 16 * fac_ns_unq); diff --git a/lib_lc3plus/noise_filling.c b/lib_lc3plus/noise_filling.c index 7fac5e0f72de7b66130fcbbd93ee99e794543d3e..1ae4c8ab8c842ec16fb42b1697c17d3215219e14 100644 --- a/lib_lc3plus/noise_filling.c +++ b/lib_lc3plus/noise_filling.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,8 +13,8 @@ void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) { - LC3_INT zeroLines[MAX_LEN] = {0}; - LC3_INT nTransWidth = 0, startOffset = 0, i = 0, j = 0, k = 0, start = 0, end = 0, allZeros = 0, kZeroLines = 0; + LC3_INT zeroLines[MAX_LEN]; + LC3_INT nTransWidth, startOffset, j, k, nzeros = 0, kZeroLines; LC3_FLOAT fac_ns = 0; switch (frame_dms) @@ -27,6 +27,12 @@ void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, nTransWidth = 1; startOffset = 12; break; +#ifdef CR8_G_ADD_75MS + case 75: + nTransWidth = 2; + startOffset = 18; + break; +#endif case 100: nTransWidth = 3; startOffset = 24; @@ -37,25 +43,44 @@ void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, j = 0; - for (k = startOffset; k < bw_stopband; k++) { - allZeros = 1; - - start = k - nTransWidth; - end = MIN(bw_stopband - 1, k + nTransWidth); - - for (i = start; i <= end; i++) { - if (xq[i] != 0) { - allZeros = 0; - } + for (k = startOffset - nTransWidth; k < startOffset + nTransWidth; k++) + { + if (xq[k] != 0) + { + nzeros = -2 * nTransWidth - 1; + } + if (xq[k] == 0) + { + nzeros ++; + } + } + for (k = startOffset; k < bw_stopband - nTransWidth; k++) + { + if (xq[k + nTransWidth] != 0) + { + nzeros = -2 * nTransWidth - 1; + } + if (xq[k + nTransWidth] == 0) + { + nzeros ++; + } + if (nzeros >= 0) + { + zeroLines[j++] = k; } + } - if (allZeros == 1) { - zeroLines[j] = k; - kZeroLines++; - j++; + for (k = bw_stopband - nTransWidth; k < bw_stopband; k++) + { + nzeros ++; + if (nzeros >= 0) + { + zeroLines[j++] = k; } } + kZeroLines = j; + for (k = 0; k < kZeroLines; k++) { nfseed = (13849 + (nfseed + 32768) * 31821) & 65535; nfseed -= 32768; diff --git a/lib_lc3plus/olpa.c b/lib_lc3plus/olpa.c index 6bec50952e5966214080221eb36e156b9ba0b176..b1b8f2171c41f6c621ff4f671c6a870d2ba2729c 100644 --- a/lib_lc3plus/olpa.c +++ b/lib_lc3plus/olpa.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,29 +11,24 @@ #include "options.h" #include "functions.h" -static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input); -static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); +static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input); +static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT32 len); -void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input) +void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input) { - LC3_INT i = 0, j = 0; - LC3_FLOAT sum = 0; /* a = 1, so denominator == 1, nothing to do here */ + LC3_INT32 i, j; - for (i = 0; i < len_input; i++) { - j = 0; - sum = 0; - for (j = 0; (j < len_buf) && (j <= i); j++) { - sum += buf[j] * in[i - j]; - } - out[i] = sum; + j = 0; + for (i = 4; i < len_input; i += 2) { + out[j++] = (buf[0] * in[i]) + (buf[1] * in[i - 1]) + (buf[2] * in[i - 2]) + (buf[3] * in[i - 3]) + (buf[4] * in[i - 4]); } } LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) { - LC3_INT max_i = 0, i = 0; + LC3_INT max_i = 0, i; LC3_FLOAT max = in[0]; if (len <= 0) { @@ -50,52 +45,84 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) return max_i; } -void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, LC3_INT* T0_out, - LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms) +void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, +#ifdef CR9_F_PITCH_WIN_LEN_FIX + LC3_INT* pitch_flag, +#endif + LC3_INT* T0_out, LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms) { LC3_FLOAT norm_corr = 0, sum = 0, sum0 = 0, sum1 = 0, sum2 = 0, norm_corr2 = 0, *s6k4; - LC3_FLOAT buf[LEN_6K4 + MAX_PITCH_6K4] = {0}, filt_out[LEN_12K8 + 3] = {0}, d_wsp[LEN_6K4] = {0}, R0[RANGE_PITCH_6K4] = {0}, R[RANGE_PITCH_6K4] = {0}; /* constant length */ - LC3_INT i = 0, j = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0; - + LC3_FLOAT buf[LEN_6K4 + MAX_PITCH_6K4 + MAX_LEN], R0[RANGE_PITCH_6K4]; /* constant length */ + LC3_INT i = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0, delta = 0; - mem_in_len = MAX_PITCH_6K4; len2 = len / 2; +#ifdef CR9_F_PITCH_WIN_LEN_FIX + switch(frame_dms) + { + case 50: + delta = len / 2; + acflen = len2 * 2; + break; + + case 25: + delta = 3*(len /2); + acflen = len2*4; + break; + + default: +#endif + delta = 0; acflen = len2; +#ifdef CR9_F_PITCH_WIN_LEN_FIX + } +#endif + + mem_in_len = MAX_PITCH_6K4 + delta; + +#ifndef CR9_F_PITCH_WIN_LEN_FIX if (frame_dms == 25) { mem_in_len += 16; acflen += 16; } +#endif /* Downsampling */ move_float(buf, mem_s12k8, 3); move_float(&buf[3], s_12k8, len); move_float(mem_s12k8, &buf[len], 3); - filter_olpa(buf, filt_out, olpa_down2, 5, len + 3); - for (i = 4, j = 0; i < len + 3; i = i + 2) { - d_wsp[j] = filt_out[i]; - j++; - } + filter_olpa(buf, R0, olpa_down2, len + 3); /* Compute autocorrelation */ +#ifdef CR9_F_PITCH_WIN_LEN_FIX + s6k4 = &buf[mem_in_len - delta]; + move_float(&buf[mem_in_len], R0, len2); + move_float(buf, mem_s6k4, mem_in_len); + move_float(mem_s6k4, &buf[len2], mem_in_len); +#else s6k4 = &buf[mem_in_len]; move_float(buf, mem_s6k4, mem_in_len); - move_float(s6k4, d_wsp, len2); + move_float(s6k4, R0, len2); move_float(mem_s6k4, &buf[len2], mem_in_len); if (frame_dms == 25) { s6k4 = s6k4 - 16; } +#endif for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) { - sum = 0; - for (j = 0; j < acflen; j++) { - sum += s6k4[j] * s6k4[j - i]; - } + sum = mac_loop(s6k4, &s6k4[-i], acflen); R0[i - MIN_PITCH_6K4] = sum; } /* Weight autocorrelation and find maximum */ - move_float(R, R0, RANGE_PITCH_6K4); + + /* Second try in the neighborhood of the previous pitch */ + min_pitch = MAX(MIN_PITCH_6K4, *mem_old_T0 - 4); + max_pitch = MIN(MAX_PITCH_6K4, *mem_old_T0 + 4); + + L = searchMaxIndice(&R0[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 ); + T02 = L + min_pitch; + for (i = 0; i < RANGE_PITCH_6K4; i++) { R0[i] = R0[i] * olpa_acw[i]; } @@ -104,22 +131,17 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 /* Compute normalized correlation */ sum0 = sum1 = sum2 = 0; + for (i = 0; i < acflen; i++) { sum0 += s6k4[i] * s6k4[i - T0]; sum1 += s6k4[i - T0] * s6k4[i - T0]; sum2 += s6k4[i] * s6k4[i]; } sum1 = sum1 * sum2; - sum1 = LC3_SQRT(sum1) + LC3_POW(10.0, -5.0); + sum1 = LC3_SQRT(sum1) + 1.00e-05; norm_corr = sum0 / sum1; norm_corr = MAX(0, norm_corr); - /* Second try in the neighborhood of the previous pitch */ - min_pitch = MAX(MIN_PITCH_6K4, *mem_old_T0 - 4); - max_pitch = MIN(MAX_PITCH_6K4, *mem_old_T0 + 4); - L = searchMaxIndice(&R[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 ); - T02 = L + min_pitch; - if (T02 != T0) { sum0 = sum1 = sum2 = 0; for (i = 0; i < acflen; i++) { @@ -128,7 +150,7 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 sum2 += s6k4[i] * s6k4[i]; } sum1 = sum1 * sum2; - sum1 = LC3_SQRT(sum1) + LC3_POW(10.0, -5.0); + sum1 = LC3_SQRT(sum1) + 1.00e-05; norm_corr2 = sum0 / sum1; norm_corr2 = MAX(0, norm_corr2); @@ -138,7 +160,41 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 } } +#ifdef CR9_F_PITCH_WIN_LEN_FIX + switch(frame_dms) + { + case 50: + if (*pitch_flag == 1) + { + *mem_old_T0 = T0; + *pitch_flag = 0; + } + else + { + *pitch_flag += 1; + } + break; + + case 25: + if (*pitch_flag == 3) + { + *mem_old_T0 = T0; + *pitch_flag = 0; + } + else + { + *pitch_flag += 1; + } + break; + + default: +#endif *mem_old_T0 = T0; +#ifdef CR9_F_PITCH_WIN_LEN_FIX + } +#endif + *T0_out = T0 * 2.0; *normcorr_out = norm_corr; + } diff --git a/lib_lc3plus/pc_apply.c b/lib_lc3plus/pc_apply.c index 1d1bc40005b4d9382cb951570a6dbf569d5ab19a..4ca871f2fcca7b5c38ce7b24e9ebe73c41950fa3 100644 --- a/lib_lc3plus/pc_apply.c +++ b/lib_lc3plus/pc_apply.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/pc_classify.c b/lib_lc3plus/pc_classify.c index 71196edb89692cf1ebdbf8a1508e31174e92b8ae..9fa5f38d9cb232cee8f6b900c83e50d49f3ba99e 100644 --- a/lib_lc3plus/pc_classify.c +++ b/lib_lc3plus/pc_classify.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/pc_main.c b/lib_lc3plus/pc_main.c index 268ee94d2a383cf043d99089da3829907702c9c4..ead43deefe080feecf14ea8bb97cbd811945fa11 100644 --- a/lib_lc3plus/pc_main.c +++ b/lib_lc3plus/pc_main.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/pc_update.c b/lib_lc3plus/pc_update.c index 57539b50797673f624e35305a0bddb11614911b2..214ced77d07db3eaee4e9fe37d40822bc71a0b03 100644 --- a/lib_lc3plus/pc_update.c +++ b/lib_lc3plus/pc_update.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/per_band_energy.c b/lib_lc3plus/per_band_energy.c index db1b5b2d0f411925327aacd78ace3c30ce239b47..ec34c3d7dad0ac45baf99d87e4e23ebacd51c181 100644 --- a/lib_lc3plus/per_band_energy.c +++ b/lib_lc3plus/per_band_energy.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,8 +13,8 @@ void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) { - LC3_INT i = 0, j = 0, start = 0, stop = 0, maxBwBin = 0; - LC3_FLOAT sum = 0; + LC3_INT i, j, start, stop, maxBwBin; + LC3_FLOAT sum; # ifdef ENABLE_HR_MODE_FL if (hrmode) @@ -40,6 +40,11 @@ void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_ maxBwBin = maxBwBin >> 1; break; # endif +#ifdef CR8_G_ADD_75MS + case 75: + maxBwBin = (maxBwBin >> 2) * 3; + break; +#endif } for (i = 0; i < bands_number; i++) { diff --git a/lib_lc3plus/plc_classify.c b/lib_lc3plus/plc_classify.c index 619a1f7419b1301242a9bb9264b5f7fe77330c89..e45f08747d85c29eedc3fc9020ceb7852913187a 100644 --- a/lib_lc3plus/plc_classify.c +++ b/lib_lc3plus/plc_classify.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,87 @@ #include "options.h" #include "functions.h" +#ifdef CR8_A_PLC_FADEOUT_TUNING + +static LC3_INT32 change_bit_at_position(LC3_INT32 value, LC3_UINT8 bit_position, LC3_INT8 bit) +{ + LC3_INT32 helper_mask = ~(1 << bit_position); + LC3_INT32 tmp = value & helper_mask; + tmp = tmp | (bit << bit_position); + return tmp; +} + +static void update_bit_and_byte_positions(LC3_INT16 longterm_analysis_counter_max_bytebuffer, LC3_INT8 *byte_position, LC3_INT8 *bit_position) +{ + if (*bit_position == 30) + { + *bit_position = 0; + + if ((*byte_position - longterm_analysis_counter_max_bytebuffer) < -1) + { + *byte_position = *byte_position + 1; + } else { + *byte_position = 0; + } + } else { + *bit_position = *bit_position + 1; + } +} + +static void array_insert_and_shift(LC3_INT32 *array, LC3_UINT8 value, LC3_INT16 longterm_analysis_counter_max, LC3_INT16 *overall_counter, LC3_INT8 *byte_position, LC3_INT8 *bit_position) +{ + LC3_INT32 current_byte = 0; + + if (overall_counter != NULL) + { + *overall_counter = MIN(*overall_counter + 1, longterm_analysis_counter_max); + } + + current_byte = array[*byte_position]; + + current_byte = change_bit_at_position(current_byte, *bit_position, value); + + array[*byte_position] = current_byte; +} + +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER +static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 longterm_analysis_counter_max) +#else +static void array_calculate(LC3_INT32 *array_tdc, LC3_INT32 *array_ns, int length, LC3_INT16 *counter_tdc, LC3_INT16 *counter_ns, LC3_INT16 *counter_phecu, LC3_INT16 overall_counter, LC3_INT16 longterm_analysis_counter_max) +#endif +{ + int i, k; + LC3_INT32 current_byte_tdc = 0, current_byte_ns = 0; + LC3_INT16 counter_loc_tdc = 0, counter_loc_ns = 0, counter_tmp = 0; + + for (i = length - 1; i >= 0; i--) + { + current_byte_tdc = array_tdc[i]; + current_byte_ns = array_ns[i]; + + for (k = 0; k < 30; k++) + { + counter_loc_tdc += ((current_byte_tdc >> k) & 1); + counter_loc_ns += ((current_byte_ns >> k) & 1); + counter_tmp++; + + /* Break from both loops if full 2s buffer has been evaluated */ + if (counter_tmp >= longterm_analysis_counter_max) + { + i = -1; + k = 30; + break; + } + } + } + + *counter_tdc = counter_loc_tdc; + *counter_ns = counter_loc_ns; +#ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + *counter_phecu = overall_counter - counter_loc_tdc - counter_loc_ns; +#endif +} +#endif static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr); static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *bands_offset, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc); @@ -22,21 +103,46 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n ) { LC3_FLOAT sc, class; - +#ifdef CR8_A_PLC_FADEOUT_TUNING + int fs_idx_tmp; +#endif + if (plcAd) { *xcorr = 0; } +#ifdef CR8_A_PLC_FADEOUT_TUNING + fs_idx_tmp = FS2FS_IDX(fs); + /* Save statistics for 24 kHz, 48 kHz and 96 kHz */ + if ((bfi == 1) || ((bfi >= 0) && (bfi <= 2) && ((fs_idx_tmp == 2) || (fs_idx_tmp == 4) || (fs_idx_tmp == 5)))) /* Partial Concealment PC(bfi==2) requires allowing value 2 to pass thru as well */ +#else if (bfi == 1) +#endif { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (bfi == 1) + { + *nbLostCmpt = *nbLostCmpt + 1; + } +#else *nbLostCmpt = *nbLostCmpt + 1; +#endif /* Use pitch correlation at ltpf integer lag if available */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + if ((*nbLostCmpt == 1) || (bfi != 1) )/* PC(bfi==2) requires allowing 2 to pass thru as well */ +#else if (*nbLostCmpt == 1) +#endif { +#ifdef CR8_A_PLC_FADEOUT_TUNING + *concealMethod = 4; /* Noise Substitution */ + UNUSED(plcMeth); +#else *concealMethod = plcMeth; // this is a dangerous mapping! - +#endif + /* Advanced PLC */ if (pitch_int > 0) { @@ -44,24 +150,53 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n plc_xcorr_lc(plcAd->pcmbufHist, plcAd->max_len_pcm_plc, pitch_int, framelength, frame_dms, fs, xcorr); spectral_centroid_lc(plcAd->scf_q_old, tilt, band_offsets, bands_number, framelength, fs, &sc); - class = *xcorr * 7640.0/32768.0 - sc - 5112.0/32768.0; - + class = *xcorr * 7640.0 / 32768.0 - sc - 5112.0 / 32768.0; + if (class <= 0) { if (frame_dms == 100 && hrmode == 0) { *concealMethod = 2; /* PhaseEcu selected */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif } else { +#ifndef CR9_G_PLC_NS_TDC_FIX *concealMethod = 4; /* Noise Substitution */ +#endif +#ifdef CR8_A_PLC_FADEOUT_TUNING + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif } } +#ifdef CR8_A_PLC_FADEOUT_TUNING + else { + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 1, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 0, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + } +#endif } else { *concealMethod = 4; /* Noise Substitution */ +#ifdef CR8_A_PLC_FADEOUT_TUNING + array_insert_and_shift(plcAd->plc_longterm_advc_tdc, 0, plcAd->longterm_analysis_counter_max, &plcAd->overall_counter, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); + array_insert_and_shift(plcAd->plc_longterm_advc_ns, 1, plcAd->longterm_analysis_counter_max, NULL, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif } + +#ifdef CR8_A_PLC_FADEOUT_TUNING +# ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, plcAd->longterm_analysis_counter_max); +# else + array_calculate(plcAd->plc_longterm_advc_tdc, plcAd->plc_longterm_advc_ns, plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_plcTdc, &plcAd->longterm_counter_plcNsAdv, &plcAd->longterm_counter_plcPhaseEcu, plcAd->overall_counter, plcAd->longterm_analysis_counter_max); +# endif + update_bit_and_byte_positions(plcAd->longterm_analysis_counter_max_bytebuffer, &plcAd->longterm_counter_byte_position, &plcAd->longterm_counter_bit_position); +#endif } } } diff --git a/lib_lc3plus/plc_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c index 4a1111a2c7317f29d815fe0c0346d314b9e17569..a81af2218b920bddbda5b181b32ba4a55fced329 100644 --- a/lib_lc3plus/plc_compute_stab_fac.c +++ b/lib_lc3plus/plc_compute_stab_fac.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_damping_scrambling.c b/lib_lc3plus/plc_damping_scrambling.c index ecea32be5fa151684a7ced58dd0c5d7e04b045d7..a863c1621a01fd8bf5ace1b40d58044fb32ec66b 100644 --- a/lib_lc3plus/plc_damping_scrambling.c +++ b/lib_lc3plus/plc_damping_scrambling.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -17,7 +17,11 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, - LC3_FLOAT *cum_fflcAtten) + LC3_FLOAT *cum_fflcAtten +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ) { LC3_INT32 processDampScramb; @@ -31,15 +35,33 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, { processDampScramb = 1; } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (ns_nbLostCmpt == 1) + { + *cum_fading_slow = 1; + *cum_fading_fast = 1; + *cum_fflcAtten = 1; + } +#endif + if ( bfi == 1 ) { processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt, stabFac, processDampScramb, cum_fflcAtten, - pitch_present_bfi1, frame_dms, cum_fading_slow, cum_fading_fast, ns_seed, 0); + pitch_present_bfi1, frame_dms, cum_fading_slow, cum_fading_fast, ns_seed, 0 +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); } else /* bfi == 2 */ { processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt_pc, stabFac, processDampScramb, cum_fflcAtten, - pitch_present_bfi2, frame_dms, cum_fading_slow, cum_fading_fast, pc_seed, spec_inv_idx); + pitch_present_bfi2, frame_dms, cum_fading_slow, cum_fading_fast, pc_seed, spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); processPlcUpdateSpec_fl(spec_prev, spec, yLen); } } @@ -47,13 +69,18 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, - LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx) + LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ) { LC3_INT32 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, x, b, i, ad_ThreshFac_start; LC3_FLOAT slow, fast, linFuncStartStop, randThreshold, ad_ThreshFac_end, ad_threshFac, frame_energy, mean_energy, energThreshold, fac, m, n, fflcAtten, cum_fading_slow_local, cum_fading_fast_local; frame_energy = 0; +#ifndef CR8_A_PLC_FADEOUT_TUNING /* Main process */ if (nbLostCmpt == 1) { @@ -61,6 +88,7 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n *cum_fading_fast = 1; *cum_fflcAtten = 1; } +#endif slow = 0.8 + 0.2 * (*stabFac); fast = 0.3 + 0.2 * (*stabFac); @@ -75,64 +103,104 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n slow = LC3_SQRT(slow); fast = LC3_SQRT(fast); break; +#ifdef CR8_G_ADD_75MS + case 75: + slow = LC3_SQRT(LC3_SQRT(slow*slow*slow)); + fast = LC3_SQRT(LC3_SQRT(fast*fast*fast)); + break; +#endif } - *cum_fading_slow = *cum_fading_slow * slow; - *cum_fading_fast = *cum_fading_fast * fast; - - if (processDampScramb == 1) +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) { - fflcAtten = 1; - cum_fading_slow_local = *cum_fading_slow; - cum_fading_fast_local = *cum_fading_fast; - - if (spec_inv_idx == 0) - { - if (nbLostCmpt * frame_dms > PLC_FADEOUT_IN_MS * 10) - { - fflcAtten = 0; - *cum_fflcAtten = 0; - } - else if (nbLostCmpt * frame_dms > 200) - { - switch(frame_dms) - { - case 25: fflcAtten = PLC34_ATTEN_FAC_025; break; - case 50: fflcAtten = PLC34_ATTEN_FAC_050; break; - case 100: fflcAtten = PLC34_ATTEN_FAC_100; break; - } - } - - - *cum_fflcAtten = *cum_fflcAtten * fflcAtten; - cum_fading_slow_local = *cum_fading_slow * *cum_fflcAtten; - cum_fading_fast_local = *cum_fading_fast * *cum_fflcAtten; - } +#endif + *cum_fading_slow = *cum_fading_slow * slow; + *cum_fading_fast = *cum_fading_fast * fast; +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif + + if (processDampScramb == 1) + { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0) + { + if (nbLostCmpt < (4 * (100.0 / (LC3_FLOAT)frame_dms))) { + cum_fading_slow_local = 1.0; + } + else if (nbLostCmpt < (8 * (100.0 / (LC3_FLOAT)frame_dms))) { + cum_fading_slow_local = 0.9; + } + else { + cum_fading_slow_local = 0.85; + } - if (pitch_present == 0) - { - plc_start_inFrames = 1; - } else { - plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms / 10.0)); - } + *cum_fading_slow = *cum_fading_slow * cum_fading_slow_local; + cum_fading_slow_local = *cum_fading_slow; + } + else { +#endif + fflcAtten = 1; + cum_fading_slow_local = *cum_fading_slow; + cum_fading_fast_local = *cum_fading_fast; - plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms / 10.0)); - plc_duration_inFrames = plc_end_inFrames - plc_start_inFrames; + if (spec_inv_idx == 0) + { + if (nbLostCmpt * frame_dms > PLC_FADEOUT_IN_MS * 10) + { + fflcAtten = 0; + *cum_fflcAtten = 0; + } + else if (nbLostCmpt * frame_dms > 200) + { + switch (frame_dms) + { + case 25: fflcAtten = PLC34_ATTEN_FAC_025; break; + case 50: fflcAtten = PLC34_ATTEN_FAC_050; break; +#ifdef CR8_G_ADD_75MS + case 75: fflcAtten = PLC34_ATTEN_FAC_075; break; +#endif + case 100: fflcAtten = PLC34_ATTEN_FAC_100; break; + } + } - if (nbLostCmpt <= plc_start_inFrames) - { - linFuncStartStop = 1; - } else if (nbLostCmpt >= plc_end_inFrames) - { - linFuncStartStop = 0; - } else { - x = nbLostCmpt; - m = -1.0 / plc_duration_inFrames; - b = -plc_end_inFrames; - linFuncStartStop = m * (x + b); - } - - randThreshold = -32768 * linFuncStartStop; + + *cum_fflcAtten = *cum_fflcAtten * fflcAtten; + cum_fading_slow_local = *cum_fading_slow * *cum_fflcAtten; + cum_fading_fast_local = *cum_fading_fast * *cum_fflcAtten; + } + + if (pitch_present == 0) + { + plc_start_inFrames = 1; + } + else { + plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms / 10.0)); + } + + plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms / 10.0)); + plc_duration_inFrames = plc_end_inFrames - plc_start_inFrames; + + if (nbLostCmpt <= plc_start_inFrames) + { + linFuncStartStop = 1; + } + else if (nbLostCmpt >= plc_end_inFrames) + { + linFuncStartStop = 0; + } + else { + x = nbLostCmpt; + m = -1.0 / plc_duration_inFrames; + b = -plc_end_inFrames; + linFuncStartStop = m * (x + b); + } + + randThreshold = -32768 * linFuncStartStop; +#ifdef CR8_A_PLC_FADEOUT_TUNING + } +#endif for (i = spec_inv_idx; i < yLen; i++) { @@ -146,37 +214,52 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n if (*seed < 0) { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0 || pitch_present == 0 || *seed < randThreshold ) +#else if (pitch_present == 0 || *seed < randThreshold) +#endif { spec[i] = -spec[i]; } } } - ad_ThreshFac_start = 10; - ad_ThreshFac_end = 1.2; - ad_threshFac = (ad_ThreshFac_start - ad_ThreshFac_end) * linFuncStartStop + ad_ThreshFac_end; - - if (spec_inv_idx < yLen) +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) { - for (i = spec_inv_idx; i < yLen; i++) +#endif + ad_ThreshFac_start = 10; + ad_ThreshFac_end = 1.2; + ad_threshFac = (ad_ThreshFac_start - ad_ThreshFac_end) * linFuncStartStop + ad_ThreshFac_end; + + if (spec_inv_idx < yLen) + { + for (i = spec_inv_idx; i < yLen; i++) + { + frame_energy = frame_energy + (spec[i] * spec[i]); + } + + mean_energy = frame_energy * 1 / (yLen - spec_inv_idx); + } + else { - frame_energy = frame_energy + (spec[i] * spec[i]); + mean_energy = 0; } - mean_energy = frame_energy * 1 / (yLen - spec_inv_idx); + energThreshold = LC3_SQRT(ad_threshFac * mean_energy); + fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; +#ifdef CR8_A_PLC_FADEOUT_TUNING } - else - { - mean_energy = 0; - } - - energThreshold = LC3_SQRT(ad_threshFac * mean_energy); - fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; +#endif for (i = spec_inv_idx; i < yLen; i++) { +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0 || LC3_FABS(spec[i]) < energThreshold ) +#else if (LC3_FABS(spec[i]) < energThreshold) +#endif { m = cum_fading_slow_local; n = 0; diff --git a/lib_lc3plus/plc_main.c b/lib_lc3plus/plc_main.c index df3fd184d903c169de288fd2630816b027129b3f..4fc19f6053d6fe8ffd8c3102462d7dd3ab938a11 100644 --- a/lib_lc3plus/plc_main.c +++ b/lib_lc3plus/plc_main.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -24,6 +24,16 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* LC3_INT16 prev_bfi_plc2; LC3_FLOAT phEcu_env_stab_local[1]; LC3_FLOAT phEcu_pfind_sens[1]; + +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT16 consecutiveLostThreshold = 0; +#endif + +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + LC3_INT16 thresh_tdc_cnt; + LC3_INT16 thresh_ns_cnt; + LC3_INT16 thresh_tdc_ns_cnt; +#endif prev_bfi_plc2 = 1; if (PlcSetup->nbLostCmpt == 0) @@ -53,14 +63,114 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* if (bfi == 1) { +# ifdef CR8_A_PLC_FADEOUT_TUNING + switch(decoder->frame_dms) + { + case 25: + consecutiveLostThreshold = 16; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_025_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_025_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_025_DMS_TDC_NS_CNT; +#endif + break; + case 50: consecutiveLostThreshold = 8; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_050_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_050_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_050_DMS_TDC_NS_CNT; +#endif + break; + case 75: consecutiveLostThreshold = 6; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_075_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_075_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_075_DMS_TDC_NS_CNT; +#endif + break; + case 100: consecutiveLostThreshold = 4; +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + thresh_tdc_cnt = THRESH_100_DMS_TDC_CNT; + thresh_ns_cnt = THRESH_100_DMS_NS_CNT; + thresh_tdc_ns_cnt = THRESH_100_DMS_TDC_NS_CNT; +#endif + break; + default: assert(0); + } + + if (decoder->fs_idx == 2 || decoder->fs_idx >= 4) + { +#ifdef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + if (PlcAdvSetup->longterm_counter_plcTdc < thresh_tdc_cnt){ + PlcAdvSetup->plc_fadeout_type = 1; + } + else if (PlcAdvSetup->longterm_counter_plcNsAdv < thresh_ns_cnt){ + PlcAdvSetup->plc_fadeout_type = 1; + } + else if (PlcAdvSetup->longterm_counter_plcTdc + PlcAdvSetup->longterm_counter_plcNsAdv < thresh_tdc_ns_cnt){ + PlcAdvSetup->plc_fadeout_type = 1; + } + else { + PlcAdvSetup->plc_fadeout_type = 0; + } +#else + if (((PlcAdvSetup->longterm_counter_plcPhaseEcu < PlcAdvSetup->longterm_counter_plcTdc*FAC1_FADEOUT) || + (PlcAdvSetup->longterm_counter_plcPhaseEcu < PlcAdvSetup->longterm_counter_plcNsAdv*FAC1_FADEOUT)) && + (PlcAdvSetup->longterm_counter_plcTdc / (PlcAdvSetup->longterm_counter_plcNsAdv + LC3_EPS) < FAC2_FADEOUT)) + { + PlcAdvSetup->plc_fadeout_type = 0; + } else { + if ((PlcAdvSetup->longterm_counter_plcPhaseEcu > FAC3_FADEOUT * PlcAdvSetup->longterm_counter_plcTdc) || + (PlcAdvSetup->longterm_counter_plcPhaseEcu > FAC3_FADEOUT * PlcAdvSetup->longterm_counter_plcNsAdv)) + { + PlcAdvSetup->plc_fadeout_type = 1; + } else { + PlcAdvSetup->plc_fadeout_type = 0; + } + } +#endif + + if ((PlcAdvSetup->overall_counter - (int)(PLC_LONGTERM_ANALYSIS_STARTUP_FILL * PlcAdvSetup->longterm_analysis_counter_max)) < 0) + { + PlcAdvSetup->plc_fadeout_type = 0; + } +#ifndef CR9_H_REMOVE_SWITCH_TO_PLC_NS + if (PlcSetup->nbLostCmpt >= consecutiveLostThreshold && PlcAdvSetup->plc_fadeout_type == 1) + { + if ( h_DecSetup->concealMethod == 3 ) + { + h_DecSetup->concealMethod = 4; + } + } +#endif +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + if (h_DecSetup->rel_pitch_change > REL_PITCH_THRESH && hrmode == 1 && (decoder->frame_dms == 50 || decoder->frame_dms == 25) ){ + PlcAdvSetup->plc_fadeout_type = 2; + } else +#endif + if ( h_DecSetup->concealMethod != 2 ) { + /* not PhECU */ + if (PlcSetup->nbLostCmpt < consecutiveLostThreshold ) + { + PlcAdvSetup->plc_fadeout_type = 0; + } + } + } else { + PlcAdvSetup->plc_fadeout_type = 0; + } +# endif + +#ifdef PLC_CR8_A_PRINTF + printf("plc_fadeout_type = %d\n", PlcAdvSetup->plc_fadeout_type); +#endif switch (h_DecSetup->concealMethod) { case 2: { LC3_FLOAT pitch_fl_c; - + assert(decoder->fs_idx == floor(decoder->fs / 10000)); - // phaseECU supports only 10ms framing + /* phaseECU supports only 10ms framing*/ assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100); if (decoder->frame_dms != 100) @@ -155,6 +265,10 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* , &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft) +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,PlcAdvSetup->plc_fadeout_type, + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag) /* nonpure tone flag */ +#endif ); @@ -162,8 +276,7 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* h_DecSetup->imdct_mem, synth); move_float(syntM_fl_c, synth, decoder->frame_length); - - + } } break; @@ -180,7 +293,11 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* processTdcApply_fl(ltpf_pitch_int, &PlcAdvSetup->PlcTdcSetup.preemphFac, A, PlcAdvSetup->PlcTdcSetup.lpcorder, PlcAdvSetup->pcmbufHist, PlcAdvSetup->max_len_pcm_plc, decoder->frame_length, decoder->frame_dms, decoder->fs, PlcSetup->nbLostCmpt, decoder->frame_length - decoder->la_zeroes, &PlcAdvSetup->stabFac, PlcAdvSetup->PlcTdcSetup.harmonicBuf, PlcAdvSetup->PlcTdcSetup.synthHist, &PlcAdvSetup->PlcTdcSetup.fract, &PlcAdvSetup->PlcTdcSetup.seed, &PlcAdvSetup->PlcTdcSetup.gain_c, - &h_DecSetup->alpha, synth); + &h_DecSetup->alpha, synth +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,PlcAdvSetup->plc_fadeout_type +#endif +); processTdcTdac_fl(synth, decoder->imdct_win, decoder->frame_length, decoder->la_zeroes, h_DecSetup->imdct_mem); memmove(syntM_fl_c, synth, sizeof(LC3_FLOAT) * decoder->frame_length); diff --git a/lib_lc3plus/plc_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c index 4913ee53e5f2ac954d9f1e12f81b5979c49baf60..92f8b3cf214f7cc84abc33fa51dacbec4330cd81 100644 --- a/lib_lc3plus/plc_noise_substitution.c +++ b/lib_lc3plus/plc_noise_substitution.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c index 11ebf276b151b9c4f58f37de5632863aa8341ae1..2a580024f037c2bb842ba777a1e73b2a8b9e2e45 100644 --- a/lib_lc3plus/plc_phecu_f0_refine_first.c +++ b/lib_lc3plus/plc_phecu_f0_refine_first.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c index c25466c3e995a0310ce70c92f81070558dc6d87e..4aebbfa88545a47e611bcf6fb992af5e819eaaae 100644 --- a/lib_lc3plus/plc_phecu_fec_hq.c +++ b/lib_lc3plus/plc_phecu_fec_hq.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c index 5b1978bcabfe7995abd483962079984e38e1ab71..112d965a4963e6775c418c137e4c37c6fb8dbf1b 100644 --- a/lib_lc3plus/plc_phecu_hq_ecu.c +++ b/lib_lc3plus/plc_phecu_hq_ecu.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,6 +13,7 @@ #include "functions.h" + void plc_phEcu_hq_ecu( LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, LC3_FLOAT *xfp, LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, LC3_INT32 fs, @@ -24,7 +25,12 @@ void plc_phEcu_hq_ecu( LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, LC3_FLOAT *corr_phase_dbg, - Fft *PhEcu_Fft, Fft *PhEcu_Ifft) + Fft *PhEcu_Fft, Fft *PhEcu_Ifft +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type, LC3_INT16 *nonpure_tone_flag_ptr /* nonpure tone flag */ +#endif + + ) { LC3_INT32 i; LC3_INT32 fs_idx, L, Lprot, n_grp, Lecu, LXsav, Lxfp_inuse; @@ -48,6 +54,8 @@ void plc_phEcu_hq_ecu( Lxfp_inuse = (LC3_INT32)(L*(3.75/10.0)); } + + UNUSED(env_stabPtr); UNUSED(xsubst_dbg); UNUSED(X_out_m_dbg); @@ -69,12 +77,20 @@ void plc_phEcu_hq_ecu( xfp_local_rnd[i] = 0.0; } } +#ifdef CR8_A_PLC_FADEOUT_TUNING + *nonpure_tone_flag_ptr = -1; /* set nonpure tone flag for new analysis */ +#endif *time_offs = 0; burst_len = (*time_offs / L + 1); plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr , old_grp_shape, old_EwPtr, st_beta_mute, - st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL); + st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL + +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,plc_fadeout_type +#endif + ); plc_phEcu_spec_ana(xfp_local_rnd, Lprot, winWhr, pfind_sensPtr, plocs, n_plocs, f0est, X_sav_m, &LXsav, f0binPtr, f0ltpGainPtr, fs_idx, PhEcu_Fft); } @@ -85,7 +101,11 @@ void plc_phEcu_hq_ecu( burst_len = ((*time_offs / L) + 1); plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr, old_grp_shape, old_EwPtr, st_beta_mute, - st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL); + st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,plc_fadeout_type +#endif + ); } @@ -100,6 +120,12 @@ void plc_phEcu_hq_ecu( /* inplace X_out_m update */ plc_phEcu_subst_spec(plocs, *n_plocs, f0est, *time_offs, X_out_m, LXsav, mag_chg, &seed, alpha, beta, st_Xavg, t_adv, Lprot, delta_corr, +#ifdef CR8_A_PLC_FADEOUT_TUNING + plc_fadeout_type, + nonpure_tone_flag_ptr, /* nonpure_tone_flag , a state updated here */ +#endif + + NULL, NULL, NULL); diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis.c b/lib_lc3plus/plc_phecu_lf_peak_analysis.c index 0bcc98d7a489b37cdf94f118131188d17ca1a5ba..225aa52560ca009e822fc97eae5c650e400bbfbf 100644 --- a/lib_lc3plus/plc_phecu_lf_peak_analysis.c +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c index 0e6570743ae7f8464e17d0b891a389ee3b1cccd0..e56cb3dd759de8a5985f1cecc0c9675fd9d257d5 100644 --- a/lib_lc3plus/plc_phecu_rec_frame.c +++ b/lib_lc3plus/plc_phecu_rec_frame.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -51,7 +51,12 @@ void plc_phEcu_rec_frame(Complex *X_in, UNUSED(ifft_out_dbg); UNUSED(xsubst_dbg); UNUSED(xsubst_LL); - fs_idx = FRAME2FS_IDX(L); + +#ifdef CR8_A_PLC_FADEOUT_TUNING + fs_idx = FRAME2FS_IDX_10MS(L); +#else + fs_idx = FRAME2FS_IDX(L); +#endif hannOla = hannOla_wins[fs_idx]; X_in[0].i = X_in[Lprot / 2].r; /* move fs/2 real to imag part of X_in[0]*/ diff --git a/lib_lc3plus/plc_phecu_setf0hz.c b/lib_lc3plus/plc_phecu_setf0hz.c index b14327e2b2af0f4c04c1f9bc633e0ac06a1a2114..7bdb0a8c5cf4aedf41d4c55cc31b2b62fb2bb792 100644 --- a/lib_lc3plus/plc_phecu_setf0hz.c +++ b/lib_lc3plus/plc_phecu_setf0hz.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c index b49690030596c08363f4168b5b6d1abd8c9d3b7b..313b33877718c764ef49353db37b38e8334ce8e2 100644 --- a/lib_lc3plus/plc_phecu_spec_ana.c +++ b/lib_lc3plus/plc_phecu_spec_ana.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_subst_spec.c b/lib_lc3plus/plc_phecu_subst_spec.c index 43f806339b8ed85c9b5a1ebae1f1586210dda817..d494af826f5806ccfb4fe1bacf13074293a3cd28 100644 --- a/lib_lc3plus/plc_phecu_subst_spec.c +++ b/lib_lc3plus/plc_phecu_subst_spec.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,35 +13,47 @@ #include "functions.h" #include "constants.h" - static LC3_INT32 own_rand(LC3_INT32 seed); static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOAT cos_F); static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F); +#ifdef CR8_A_PLC_FADEOUT_TUNING + +#define ONE_SIDED_SINE_WIDTH (4) /* expected pure sine main lobe maximum width (4+1+4) bins *62.5 hz/bin => approx 560 Hz total width */ + +static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_INT32 n_plocs, const Complex* X, const LC3_FLOAT* Xavg, const LC3_INT32 Lprot); +#endif + void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, - LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, LC3_FLOAT *corr_phase_dbg, + LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT16 fadeout, /* need for DC muting */ + LC3_INT16* nonpure_tone_flag_ptr, +#endif + LC3_FLOAT *corr_phase_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg) { LC3_INT32 i, i2, lprotBy2Minus1, one_peak_flag_mask, noise_mag_scale; LC3_INT32 t_adv; - LC3_FLOAT corr_phase[MAX_PLC_NPLOCS] = {0}; - LC3_FLOAT cos_F, mag_chg_local, alpha_local, beta_local, tmp; + LC3_FLOAT corr_phase[MAX_PLC_NPLOCS] = {0}; + LC3_FLOAT cos_F, mag_chg_local, alpha_local, beta_local, tmp; Complex X_i, X_i_new; LC3_INT32 segmentLen, e; LC3_FLOAT Xph; LC3_FLOAT seed_local; - LC3_INT32 binCounter, subInd; - + LC3_INT32 binCounter = 1, subInd = 0; +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT16 fs_idx; +#endif + UNUSED(corr_phase_dbg); UNUSED(X_i_new_re_dbg); UNUSED(X_i_new_im_dbg); seed_local = (LC3_FLOAT) *seed; - - lprotBy2Minus1 = imin(320, Lprot/2 - 1); /* limit to 20 KHz */ - + lprotBy2Minus1 = imin(320, Lprot/2 - 1); /* limit to 20 KHz */ t_adv = t_adv_in + time_offs; @@ -49,15 +61,33 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv; } - // EVOLVE PHASE ----------------- - binCounter = 1; - subInd = 0; one_peak_flag_mask = -1; +#ifdef CR8_A_PLC_FADEOUT_TUNING + fs_idx = (LC3_INT16)LC3_FLOOR((LC3_FLOAT)Lprot / 160.0); /* aquire, fs_idx for 10 ms frame sizes */ + if (n_plocs < 3 && n_plocs > 0) + { + one_peak_flag_mask = 0; /* initial crude single tone detection, only using n_plocs as a result from peak_locator() dynamics as input */ + + if ( (*nonpure_tone_flag_ptr < 0 ) + && ( (fs_idx == 2) /*SemiSWB 24 kHz */ || (fs_idx >= 4) /* FB 48 kHz */ ) + ) + { + /* in the first lost frame analyze spectra to possibly reverse initial pure sine assumption */ + *nonpure_tone_flag_ptr = plc_phEcu_nonpure_tone_ana(plocs, n_plocs, X, Xavg, Lprot ); + } + + if ( *nonpure_tone_flag_ptr > 0 ) { + one_peak_flag_mask = -1; /* actually revert single pure tone detection */ /* 0-> mute all surrounding valley bins in evolution , 0xff -> generate noise in all valleys */ + } + + } +#else if (n_plocs < 3 && n_plocs > 0) { one_peak_flag_mask = 0; } +#endif noise_mag_scale = 0; if (n_plocs == 0 || time_offs != 0) { @@ -69,6 +99,32 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, X[X_len-1] = realtoc(0); } +#ifdef CR8_A_PLC_FADEOUT_TUNING +#if 0 + /* align DC fs/2 muting to BASOP */ +#endif + /* binary selection of fadeout scheme */ + assert(PLC2_FADEOUT_LONG_IN_MS >= PLC2_FADEOUT_IN_MS_MIN && PLC2_FADEOUT_IN_MS >= PLC2_FADEOUT_IN_MS_MIN); + assert(PLC2_FADEOUT_LONG_IN_MS <= PLC2_FADEOUT_IN_MS_MAX && PLC2_FADEOUT_IN_MS <= PLC2_FADEOUT_IN_MS_MAX); + i = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; + + if (fadeout != 0) + { + i = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; + } + + /* calculate local burst_len for securing DC and fs/2 muting */ + i2 = (time_offs / ((Lprot * 100) / 160)) + 1; /* burst_len */ + + if (i2 > (fade_scheme_tab[i][1] + 1)) + { + /* start DC scaling attenuation */ + X[0].r = alpha[0] * X[0].r; + + /* start fs/by2 attenuation */ + X[X_len - 1].r = alpha[(xavg_N_grp[fs_idx] - 1)] * X[X_len - 1].r; + } +#endif if (n_plocs != 0) { for (i = 0; i < n_plocs; i++) { @@ -221,11 +277,11 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, } static LC3_INT32 own_rand(LC3_INT32 seed) { - LC3_INT32 retSeed; - assert(seed <= 32767 && seed >= -32768); - retSeed = (13849 + (seed + 32768) * 31821) & 65535; - retSeed -= 32768; - assert(retSeed <= 32767 && retSeed >= -32768); + LC3_INT32 retSeed; + assert(seed <= 32767 && seed >= -32768); + retSeed = (13849 + (seed + 32768) * 31821) & 65535; + retSeed -= 32768; + assert(retSeed <= 32767 && retSeed >= -32768); return retSeed; } @@ -245,3 +301,164 @@ static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F) { return (LC3_INT32) seed; } + +#ifdef CR8_A_PLC_FADEOUT_TUNING + +static LC3_INT16 plc_phEcu_nonpure_tone_ana(const LC3_INT32* plocs, const LC3_INT32 n_plocs, const Complex* X, const LC3_FLOAT* Xavg, const LC3_INT32 Lprot) +{ + + LC3_INT16 nonpure_tone_detect; + LC3_INT16 n_ind, tone_ind, low_ind, high_ind; + LC3_FLOAT peak_amp, peak_amp2, valley_amp, x_abs[(1 + 2 * ONE_SIDED_SINE_WIDTH + 2 * 1)]; + LC3_INT16 sineband_ind_low, sineband_ind_high; + LC3_INT16 i, fs_idx, N_grp; + LC3_FLOAT tmp, tmp_dB, tot_inc_HF, tot_inc_LF; + + + + /* use compressed hearing sensitivity curve to allow more deviation in highest and lowest bands */ + /* ROM table LC3_FLOAT scATHFx[MAX_LGW - 1] */ + + /* init */ + nonpure_tone_detect = 0; + tot_inc_HF = 0.0; + tot_inc_LF = 0.0; + + /* limit single sine optimization to when 2 peaks are close enough to represent a single sinusoid */ + if (n_plocs == 2 && (plocs[1] - plocs[0]) >= ONE_SIDED_SINE_WIDTH) /* NB, plocs is an ordered vector */ + { + nonpure_tone_detect |= 0x1; + } + + /* local bin wise dynamics analysis, if 2 peaks, we do the analysis based on the location of the largest peak */ + { + tone_ind = 0; + plc_phEcu_fft_spec2_sqrt_approx(&(X[plocs[0]]), 1, &peak_amp); /* get 1st peak amplitude = approx_sqrt(Re^2+Im^2) */ + + + if ((n_plocs - 2) == 0) + { + plc_phEcu_fft_spec2_sqrt_approx(&(X[plocs[1]]), 1, &peak_amp2); /* get 2nd peak amplitude */ + if (peak_amp2 > peak_amp) + { + tone_ind = 1; + peak_amp = peak_amp2; + } + } + + low_ind = MAX(1, plocs[tone_ind] - (ONE_SIDED_SINE_WIDTH + 1)); /* DC is not allowed as valley */ + high_ind = MIN((Lprot >> 1) - 2, plocs[tone_ind] + (ONE_SIDED_SINE_WIDTH + 1)); /* Fs/2 is not allowed as valley */ + + n_ind = high_ind - low_ind + 1; + + /* find lowest amplitudes around the assumed main lobe center location */ + plc_phEcu_fft_spec2_sqrt_approx(&(X[low_ind]), n_ind, x_abs); + valley_amp = peak_amp; + for (i = 0; i < n_ind; i++) { + valley_amp = MIN(x_abs[i], valley_amp); + } + + /* at least a localized amplitude ratio of 16 (24 dB) required to declare a pure sinusoid */ + if (peak_amp < 16 * valley_amp) /* 1/16 easily implemented in BASOP */ + { + + nonpure_tone_detect |= 0x2;/* not a pure tone due to too low local SNR */ + + } + } + + /* analyze LF/ HF bands energy dynamics vs the assumed single tone band ( one or two peaks found) */ + { + fs_idx = (LC3_INT16)floor(Lprot / 160); /* fs_idx */ + assert(fs_idx < 5); + + /* Xavg , is a vector of rather rough MDCT based band energy estimates in perceptually motivated bands. from approx the last 26 ms of synthesis */ + + /* eval amplitude relations for assumed tonal band vs lower and higher bands */ + N_grp = xavg_N_grp[fs_idx]; /* { 4 NB , 5 WB , 6 SSWB , 7 SWB, 8 FB }; */ + + /* establish band(s) with assumed sinusoid tone */ + /* if tone freq location is below first MDCT-band definition, use first band as location anyway */ + i = 0; /* band 0 , 1 , 2 , 3 , ...*/ + while (plocs[tone_ind] >= gwlpr[i + 1]) { /* gwplr= [ 1, 12(750Hz), 20(1250Hz) , 36 , .. */ + /* dct-inds "0"...11, 12...19, 20...35, 36 ... */ + i++; + } + sineband_ind_low = i; + sineband_ind_high = i; /* typically in the same band as low */ + + /* a single tone may end up on a band border + , handle case when assumed tone is more or less right in between two perceptual bands +/-4 62.5 Hz */ + if ((sineband_ind_high > 0) && + (plocs[tone_ind] - ONE_SIDED_SINE_WIDTH) >= gwlpr[sineband_ind_high + 1] + ) { + sineband_ind_low = sineband_ind_high - 1; + } + + if ( (sineband_ind_low < (N_grp - 1)) && + (plocs[tone_ind] + ONE_SIDED_SINE_WIDTH) >= gwlpr[sineband_ind_low + 1] + ) { + sineband_ind_high = sineband_ind_low + 1; + } + } + + + + /* intraframe(26 ms), weighted LB and HB envelope dynamics/variation analysis */ + /* envelope analysis , + require at least two HF or two LF bands in the envelope taper/roll-off analysis , otherwise skip this condition */ + + + if (nonpure_tone_detect == 0 && + (((sineband_ind_high + 2) < N_grp) || + ((sineband_ind_low - 2) >= 1) + ) + ) + { + /* delta taper-off analysis solution, less sensitive to input bandwidth limitation and levels */ + +#if 0 + /* note: in BASOP the Xavg ratios below are calculated in log2 domain on a maximally upshifted Xavg vector. + if Xavg is an all zero vector in BASOP, then the nonpure_tone_detect flag is or'ed with 0x100 , + to trigger normal valley noise generation */ +#endif + + /* verify that an assumed clean sine does not have any odd HF content indications by thresholding the accumulated delta rise in LF/HF side lobes */ + for (i = (sineband_ind_high + 1); i < (N_grp - 1); i++) { + tmp = (Xavg[i + 1] + LC3_EPS) / (Xavg[i] + LC3_EPS); + tmp_dB = 20.0*LC3_LOGTEN(tmp); + if ((Xavg[i] + LC3_EPS) > (Xavg[i + 1] + LC3_EPS)) { + tmp_dB = 0; + } + tot_inc_HF += scATHFx[i] * tmp_dB; /* i is ATH factor between band i, i+1 based on Hearing sensitivity */ + } + + /* verify that an assumed clean sine does not have any odd LF content by thresholding the accumulated LF reverse up tilt */ + for (i = MAX(0, (sineband_ind_low - 1)); i > 0; i--) { + tmp = (Xavg[i - 1] + LC3_EPS) / (Xavg[i] + LC3_EPS); + tmp_dB = 20.0*LC3_LOGTEN(tmp); /* switch to log2() to simplify BASOP */ + + if ((Xavg[i - 1] + LC3_EPS) < (Xavg[i] + LC3_EPS)) { + tmp_dB = 0; + } + tot_inc_LF += scATHFx[i - 1] * tmp_dB; /* "psycho" scale using i-1 is ATH factor between band i-1, i , based on Hearing sensitivity */ + } + + if (tot_inc_HF > 4.5){ /* 4.5 dB in log2 is 0.7474 */ + nonpure_tone_detect |= 0x10; /* still not a pure tone, too great HF side increase */ + } + + if (tot_inc_LF > 4.5) { /* 4.5 dB limit in 4.5 = 20log10(x) corresponds to limit value 0.7474 in log2(x) */ + nonpure_tone_detect |= 0x20; /* still not a pure tone, too great accumulated LF side increase */ + } + + /* verify that an assumed clean sine does not have any odd LF+HF content by thresholding the accumulated LF+HF unexpected tilt */ + if ((tot_inc_LF + tot_inc_HF) > 6.0) { /* 6 dB limit in 20log10(x) corresponds to limit value 1.0 in log2(x) */ + nonpure_tone_detect |= 0x40; /* still not a pure tone, to great LF+HF side variation/increase */ + } + } /* bands available*/ + + return nonpure_tone_detect; +} +#endif /* CR8_A_PLC_FADEOUT_TUNING */ + diff --git a/lib_lc3plus/plc_phecu_tba_per_band_gain.c b/lib_lc3plus/plc_phecu_tba_per_band_gain.c index 9f585f28dd8104991b5598f8f029df55f69d0433..507f45a647d1a6c15ca0533de989fda31fdd1fa1 100644 --- a/lib_lc3plus/plc_phecu_tba_per_band_gain.c +++ b/lib_lc3plus/plc_phecu_tba_per_band_gain.c @@ -1,19 +1,19 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - + #include "options.h" #include "defines.h" #include "functions.h" -void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) +void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) { LC3_INT32 i; @@ -39,6 +39,5 @@ void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FL } - return; + return; } - diff --git a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c index 600b9714e45865fb437ea653d8de8e2dab182a23..b4727cfd4cc77275fe9d60500b4676c32ebd5e26 100644 --- a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c +++ b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c index e5f0d3caae0d71e0600e9281e0e84f7c781489b4..3b58d92b427b0b456ac795bad23a10df60c9621c 100644 --- a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c +++ b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -40,11 +40,29 @@ const LC3_INT32 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { 32767, 31293, 29885, 28 #ifdef PLC2_FADEOUT_IN_MS #if PLC2_FADEOUT_IN_MS == 0 -/* default setting only requieres two tables */ +#ifndef CR8_A_PLC_FADEOUT_TUNING +/* default setting only requires two tables */ const Word16* const POW_ATT_TABLES[1 + 2] = { NULL, POW_ATT_TABLE1/*1 0.3dB steps */ , POW_ATT_TABLE0/*2 0.4 dB steps*/, }; +#endif #else + +#ifdef CR8_A_PLC_FADEOUT_TUNING +const LC3_INT32 POW_ATT_TABLE_p3x9_14_7[OFF_FRAMES_LIMIT + 1] = { + 32767, + 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, /* 9 times .3dB steps , 14 6 dB steps, 7 muted steps */ + 12007, 6003, 3002, 1501, 750, 375, 188, 94, 47, 23, 12, 6, 3, 1, + 0, 0, 0, 0, 0, 0, 0 }; + +const LC3_INT32 POW_ATT_TABLE_p4x9_14_7[OFF_FRAMES_LIMIT + 1] = +{ 32767, + 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, /* 9 times .4dB steps , 14 6 dB steps, 7 muted steps */ + 10825, 5413, 2706, 1353, 677, 338, 169, 85, 42, 21, 11, 5, 3, 1, + 0, 0,0,0,0,0,0 }; +#endif + + const LC3_INT32 POW_ATT_TABLE_p3x8_6[] = { 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, 3216, 1608, 804, 402, 201, 101, 50, 25, 13, 6, @@ -81,6 +99,23 @@ const LC3_INT32 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { 32, 16, 8, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +#ifdef CR8_A_PLC_FADEOUT_TUNING +#if 0 +/* POW_ATT_TABLES now ordered logically based on initial slow muting phase time */ +/* POW_ATT_TABLES[ind] is used after the initial gain==1.0 no energy muting phase */ +#endif +const LC3_INT32 *const POW_ATT_TABLES[1 + 12] = +{ NULL, +/*0.3dB col , 0.4dB col */ +/* 1*/POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6, /* 0 0.3dB, 16 6dB, 14mute */ /* 0.4dB version */ /* old short mute tabs */ +/* 3*/POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* 1 0.3dB, 15 6dB ,14mute */ /* 0.4dB version */ +/* 5*/POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* 3 0.3dB, 15 6dB , 12 mute */ /* 0.4dB version */ +/* 7*/POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* 7 0.3dB, 15 6dB , 8 mute */ /* 0.4dB version */ +/* 9*/POW_ATT_TABLE_p3x9_14_7, POW_ATT_TABLE_p4x9_14_7, /* 9 0.3dB, 14 6dB , 7 mute */ /* 0.4dB version */ /* opt 120 ms */ +/*11*/POW_ATT_TABLE1, POW_ATT_TABLE0, /* 15 0.3dB, 14 6dB , 1 mute */ /* 0.4dB version */ /* original curves */ +}; + +#else const LC3_INT32* const POW_ATT_TABLES[1 + 10] = { NULL, @@ -90,13 +125,18 @@ const LC3_INT32* const POW_ATT_TABLES[1 + 10] = POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */ POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */ }; +#endif #endif #endif void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change, LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, - LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames_dbg, LC3_FLOAT *thresh_dbg) + LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames_dbg, LC3_FLOAT *thresh_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ) { LC3_INT32 i; @@ -108,14 +148,19 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL LC3_INT32 burst_att_thresh; LC3_INT32 att_per_frame_idx; LC3_INT32 att_always, attDegreeFrames; - +#ifndef CR8_A_PLC_FADEOUT_TUNING LC3_INT32 FADEOUT_IN_MS, PLC_P800_SPEECH_FADEOUT_IN_FRAMES, PLC2_FADEOUT_IN_FRAMES, BURST_ATT_THRESH_PRE; +#endif const LC3_INT32 *TABLEQ15; +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT32 beta_mute_thr; /* time threshold in 10 ms frames to start beta - noise attenuation */ +#endif +#ifndef CR8_A_PLC_FADEOUT_TUNING LC3_INT32 BURST_ATT_THRESH; /* start attenuate with losses in a row, also starts FADE2AVG actions */ - LC3_INT32 ATT_PER_FRAME; /* initial msuic attenuation table ptr, actually implemented in table lookup! */ + LC3_INT32 ATT_PER_FRAME; /* initial msuic attenuation table ptr, actually implemented in table lookup! */ LC3_INT32 BETA_MUTE_THR; /* time threshold in 10 ms frames to start beta - noise attenuation */ - +#endif UNUSED(attDegreeFrames_dbg); /* constants setup */ @@ -123,32 +168,31 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL XavgFadeinFactor = -1.0; - if (PLC2_FADEOUT_IN_MS != 0) +#ifndef CR8_A_PLC_FADEOUT_TUNING + if (PLC2_FADEOUT_IN_MS < 0) { - if (PLC2_FADEOUT_IN_MS < 0) - { - FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as input */ - } - else - { - FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settinsg */ - } - - PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32) LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal svaleu for speech */ + FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as basic input */ + } + else + { + FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settings */ + } +#endif - PLC2_FADEOUT_IN_FRAMES = MIN(OFF_FRAMES_LIMIT, MAX(6, 3 * PLC_P800_SPEECH_FADEOUT_IN_FRAMES)); /* for PLC2 we typically maintain energy 3x longer */ +#ifndef CR8_A_PLC_FADEOUT_TUNING + PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32)LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal value for speech */ - BURST_ATT_THRESH_PRE = MIN(5, MAX(1, (1 * PLC2_FADEOUT_IN_FRAMES) / 6)); /* nominal 20-40 ms to start actual muting, will be thresh +1 fot assumed music */ + PLC2_FADEOUT_IN_FRAMES = MIN(OFF_FRAMES_LIMIT, MAX(6, 3 * PLC_P800_SPEECH_FADEOUT_IN_FRAMES)); /* for PLC2 we typically maintain energy 3x longer */ - ATT_PER_FRAME = MIN(10, MAX(2, 2 * (6 - BURST_ATT_THRESH_PRE))); /* % we let the BURST_ATT_thresh control the initial table selection */ - BURST_ATT_THRESH = MIN(BURST_ATT_THRESH_PRE, 4); - BETA_MUTE_THR = MIN(4 + (OFF_FRAMES_LIMIT / 2) + 1, MAX(4, BURST_ATT_THRESH + 1 + (LC3_INT32)LC3_POW((LC3_FLOAT)2.0,BURST_ATT_THRESH_PRE - (LC3_FLOAT)1))); /* nominal time to start mandatory decrease of Xavg */ - } + BURST_ATT_THRESH_PRE = MIN(5, MAX(1, (1 * PLC2_FADEOUT_IN_FRAMES) / 6)); /* nominal 20-40 ms to start actual muting, will be thresh +1 */ + ATT_PER_FRAME = MIN(10, MAX(2, 2 * (6 - BURST_ATT_THRESH_PRE))); /* % we let the BURST_ATT_thresh control the initial table selection */ + BURST_ATT_THRESH = MIN(BURST_ATT_THRESH_PRE, 4); + BETA_MUTE_THR = MIN(4 + (OFF_FRAMES_LIMIT / 2) + 1, MAX(4, BURST_ATT_THRESH + 1 + (LC3_INT32)LC3_POW((LC3_FLOAT)2.0, BURST_ATT_THRESH_PRE - (LC3_FLOAT)1))); /* nominal time to start mandatory decrease of Xavg */ - - /* Initialize in the same way as done in trans_burst_ana_fx(), even though this is not really needed */ +/* Initialize in the same way as done in trans_burst_ana_fx(), even though this is not really needed */ burst_att_thresh = BURST_ATT_THRESH; att_per_frame_idx = ATT_PER_FRAME; +#endif /* 10ms constants */ @@ -158,10 +202,26 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL max_increase_grp_pow_lin = (LC3_FLOAT)1.0*LC3_POW((LC3_FLOAT)10.0, max_increase_grp_pow / (LC3_FLOAT)10.0)*(LC3_FLOAT)(32767.0 / 32768.0); +#ifndef CR8_A_PLC_FADEOUT_TUNING /* envelope setting */ burst_att_thresh = BURST_ATT_THRESH + 1; att_per_frame_idx = ATT_PER_FRAME - 1; +#endif +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type != 0) + { + i = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /*a long fading table entry in fade_scheme_tab */ + } else { + i = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES; /* a shorter fading entry in fade_scheme_tab */ + } + assert(i >= 0 && i <= ((PLC2_FADEOUT_IN_MS_MAX - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES) && "fade_scheme_tab index error"); + + att_per_frame_idx = fade_scheme_tab[i][0]; + burst_att_thresh = fade_scheme_tab[i][1]; /* number of 1.0 frames before muting/mixing phase */ + /* band gain muting may can take place earlier due to a band transient */ + beta_mute_thr = fade_scheme_tab[i][2]; /* muting of Xavg contribution start when slow fadeout is over */ +#endif attDegreeFrames = 0; if (burst_len > burst_att_thresh) @@ -203,7 +263,6 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL /* transient processing */ /* transients may be both rise and decay transients !! */ - if(LC3_FABS(grp_pow_change[i]) >= thresh_tr_dB) { @@ -233,13 +292,20 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL assert(burst_len >= 2); /* states used here */ tr_dec[i] = 0; +#ifndef CR8_A_PLC_FADEOUT_TUNING if (PLC_FADEOUT_IN_MS > 0) +#endif { +#ifdef CR8_A_PLC_FADEOUT_TUNING + assert(att_per_frame_idx >= 1 && att_per_frame_idx <= (10+2)); +#else assert(att_per_frame_idx >= 1 && att_per_frame_idx <= 10); +#endif TABLEQ15 = POW_ATT_TABLES[att_per_frame_idx]; att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT) TABLEQ15[MIN(OFF_FRAMES_LIMIT, attDegreeFrames )] / (LC3_FLOAT)32768.0); /* Table idx 0...N-1 therefore no + 1 */ att_val[i] = att_val[i]; } +#ifndef CR8_A_PLC_FADEOUT_TUNING else { @@ -252,7 +318,7 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE1[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); } } - +#endif if ( (att_val[i] != 0) && (att_val[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5) ) { @@ -270,8 +336,12 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL } - +#ifdef CR8_A_PLC_FADEOUT_TUNING + /* note beta_mute decreased once per frame, not once per band */ + if (i == 0 && burst_len > beta_mute_thr) +#else if(burst_len > BETA_MUTE_THR) +#endif { *stPhECU_beta_mute = *stPhECU_beta_mute * (LC3_FLOAT)BETA_MUTE_FAC; } diff --git a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c index c860cd6ce3d69968dbd7b217ae7f363a7e791e27..d4d8f15e20c3826e4292336c35052e8928e97e38 100644 --- a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c +++ b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c @@ -1,22 +1,28 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * * estoppel or otherwise. * ******************************************************************************/ - + #include "options.h" #include "defines.h" #include "functions.h" -void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, - LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, + + +void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, + LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, - LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg) + LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif +) { LC3_FLOAT gr_pow_left[MAX_LGW]; LC3_FLOAT gr_pow_right[MAX_LGW]; @@ -28,7 +34,7 @@ void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_IN LC3_INT32 attDegreeFrames; LC3_FLOAT thresh_dbg; - + UNUSED(tr_dec_dbg); UNUSED(gpc_dbg); @@ -40,8 +46,13 @@ void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_IN } + plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , plc_fadeout_type +#endif + ); + - plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg); return; } diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c index 1a1a408f4d9d3b6216f048c34704735256eb5562..89d745543382512c6e1c01e71669034ef0d49951 100644 --- a/lib_lc3plus/plc_tdc.c +++ b/lib_lc3plus/plc_tdc.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,11 +8,11 @@ ******************************************************************************/ -#include "options.h" /***************************************************************************\ * contents/description: Main function for Time domain concealment \***************************************************************************/ +#include "options.h" #include #include "functions.h" @@ -61,6 +61,9 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + ,LC3_UINT8 plc_fadeout_type +#endif ) { LC3_FLOAT step, step_n; @@ -77,6 +80,9 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, LC3_FLOAT alphaPrev; LC3_FLOAT throttle; LC3_INT32 frame_dms_idx, nbLostFramesInRow_mod; +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + LC3_INT32 plc_fadeout_len = 0; +#endif memset(synth_mem, 0, M * sizeof(LC3_FLOAT)); memset(scratchSpace, 0, (MAX_LEN_PCM_PLC + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)); @@ -91,7 +97,20 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, beforeNextInc = beforeNextIncArray[frame_dms_idx][nbLostFramesInRow_mod]; nextInc = nextIncArray [frame_dms_idx][nbLostFramesInRow_mod]; +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + if (plc_fadeout_type == 1){ + plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS; + } + else{ + plc_fadeout_len = PLC_FADEOUT_IN_MS; + } +#endif + +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + if (nbLostCmpt_loc > plc_fadeout_len/10) +#else if (nbLostCmpt_loc > PLC_FADEOUT_IN_MS/10) +#endif { gain_p = 0; *gain_c = 0; @@ -198,7 +217,14 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, { alphaPrev = *alpha; } - + +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + if (plc_fadeout_type == 2){ + *alpha = LC3_POW(0.5,(nbLostFramesInRow + LC3_ROUND(100.0/frame_dms) - 1) * frame_dms/100.0); + } + else{ +#endif + if (nextInc != 0) { switch (nbLostCmpt_loc) @@ -231,7 +257,14 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, switch (frame_dms) { case 25: *alpha *= PLC34_ATTEN_FAC_025; break; +#ifdef CR9_J_SLOW_TDC_FADEOUT + case 50: *alpha *= PLC34_ATTEN_FAC_025; break; +#else case 50: *alpha *= PLC34_ATTEN_FAC_050; break; +#endif +#ifdef CR8_G_ADD_75MS + case 75: *alpha *= PLC34_ATTEN_FAC_075; break; +#endif case 100: *alpha *= PLC34_ATTEN_FAC_100; break; } } @@ -240,7 +273,9 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, { gain_p = *alpha; } - +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + } +#endif /*---------------------------------------------------------------* * Construct the harmonic part * * Last pitch cycle of the previous frame is repeatedly copied. * @@ -377,7 +412,11 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, *----------------------------------------------------------*/ if (beforeNextInc != 0) { +#ifdef CR9_I_INC_TDC_FADEOUT_LEN + if (nbLostCmpt_loc == plc_fadeout_len/10) +#else if (nbLostCmpt_loc == PLC_FADEOUT_IN_MS/10) +#endif { gain_h = 1; step = 1.0f/(LC3_FLOAT)N; diff --git a/lib_lc3plus/plc_tdc_tdac.c b/lib_lc3plus/plc_tdc_tdac.c index 329361b14c7f995b74a6ca2de051011c81ec088c..3c8e99b0e6ca847f3e70f2c642b151c59ed8878c 100644 --- a/lib_lc3plus/plc_tdc_tdac.c +++ b/lib_lc3plus/plc_tdc_tdac.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/plc_update.c b/lib_lc3plus/plc_update.c index a151420eb7484c7fca0aaa3af5b67f4f994eec27..4ec4e86341df96511f70cfe6d94659c44ed2ba31 100644 --- a/lib_lc3plus/plc_update.c +++ b/lib_lc3plus/plc_update.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -7,8 +7,8 @@ * estoppel or otherwise. * ******************************************************************************/ -#include "functions.h" #include "options.h" +#include "functions.h" void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, diff --git a/lib_lc3plus/quantize_spec.c b/lib_lc3plus/quantize_spec.c index 7886b4586d6e412a8c9aa44dbf004ed738ec61a6..78d3486539caabddcd41c8bd49d61f858881130e 100644 --- a/lib_lc3plus/quantize_spec.c +++ b/lib_lc3plus/quantize_spec.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,58 +11,118 @@ #include "options.h" #include "functions.h" -static LC3_INT sign(LC3_FLOAT x); - -LC3_INT sign(LC3_FLOAT x) +LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length); +LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length) { - if (x > 0) - return 1; + LC3_INT32 last_nz, lobs[4]; LC3_INT32 stage, i; + + lobs[0] = 4; + + lobs[1] = (length >> 1); /* length/2 */ + + lobs[2] = (lobs[1]+ (length >> 2)); + + lobs[3] = (lobs[2]+ (length >> 3)); + - if (x < 0) - return -1; + last_nz = 0; + + i = length; + + for (stage = 3; stage >= 0; --stage) + { + /* unmapped kernel */ + for (; i >= lobs[stage]; i -= 2) + { + if (x[i - 2] != 0) + { + last_nz = MAX(last_nz, i); + } + if (x[i - 1] != 0) + { + last_nz = MAX(last_nz, i); + } + } + if (last_nz > 0) + { + break; + } + } - return 0; + return MAX(last_nz, 2); } + void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt, LC3_INT totalBits, LC3_INT* nbits, LC3_INT* nbits2, LC3_INT fs, LC3_INT* lastnzout, LC3_INT* codingdata, LC3_INT* lsbMode, LC3_INT mode, LC3_INT target, LC3_INT hrmode) { - LC3_INT rateFlag = 0, i = 0, lastnz2 = 0, m = 0, maxlev = 0, k = 0; - LC3_INT nbits_lsb = 0; - LC3_INT c = 0; - LC3_INT a = 0, b = 0, lev1 = 0, sym = 0, t = 0, pki = 0; - LC3_INT a1_msb = 0, b1_msb = 0; - LC3_INT lastnz = 1; + LC3_INT rateFlag, i, lastnz2, m, maxlev, k; + LC3_INT nbits_lsb; + LC3_INT c; + LC3_INT a, b, lev1, sym, t, pki; + LC3_INT a1_msb, b1_msb; + LC3_INT lastnz = 1, nt_half; LC3_FLOAT offset = 0.375; + LC3_INT32 bits, bits2; +#ifdef CR9_QUANT_SPEC_REWRITE + LC3_FLOAT inv_gain; +#endif + + assert(target >= 0); + + nbits_lsb = 0; + + nt_half = nt >> 1; + rateFlag = 0; c = 0; + if (hrmode) { offset = 0.5; } - /* Quantization */ + +#ifdef CR9_QUANT_SPEC_REWRITE + inv_gain = 1.0 / gain; +#endif + for (i = 0; i < nt; i++) { - xq[i] = trunc(x[i] / gain + offset * sign(x[i])); + if (x[i] > 0) + { +#ifdef CR9_QUANT_SPEC_REWRITE + xq[i] = (LC3_INT32) ( x[i] * inv_gain + offset); +#else + xq[i] = (LC3_INT32) ( x[i] / gain + offset); +#endif + } + else + { +#ifdef CR9_QUANT_SPEC_REWRITE + xq[i] = -((LC3_INT32) (-x[i] * inv_gain + offset)); +#else + xq[i] = -((LC3_INT32) (-x[i] / gain + offset)); +#endif + } if (hrmode == 0) { assert(xq[i] <= 32767 && xq[i] >= -32768); } } /* Rate flag */ - - if ((fs < 48000 && totalBits > 320 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits > 800)) { + if (fs != 96000 && (totalBits > (160 + FS2FS_IDX(fs) * 160))) + { rateFlag = 512; } /* Init */ - if (mode == 0 && ((fs < 48000 && totalBits >= 640 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits >= 1120))) { + if (fs != 96000 && (mode == 0 && (totalBits >= (480 + FS2FS_IDX(fs) * 160)))) + { mode = 1; } /* Last non-zero 2-tuple */ - for (i = nt - 2; i >= 2; i = i - 2) { if (xq[i + 1] != 0 || xq[i] != 0) { lastnz = i + 1; @@ -70,21 +130,24 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT } } - - if (mode < 0) { + if (mode < 0) + { lastnz2 = lastnz + 1; - } else { + } + else + { lastnz2 = 2; } - *nbits = 0; - *nbits2 = 0; + bits = bits2 = 0; /* Calculate number of estimated bits */ - for (k = 0; k < lastnz; k = k + 2) { + for (k = 0; k < lastnz; k = k + 2) + { t = c + rateFlag; - if (k > nt / 2) { + if (k > nt_half) + { t += 256; } @@ -94,29 +157,36 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT b = abs(xq[k + 1]); m = MAX(a, b); - if (m == 0) { + if (m == 0) + { maxlev = -1; - } else { + } + else + { maxlev = 29 - (clz_func(MAX(m, 3)) - 1); } codingdata[1] = maxlev; if (mode <= 0) { - *nbits = *nbits + MIN(a, 1) * 2048; - *nbits = *nbits + MIN(b, 1) * 2048; + bits = bits + (MIN(a, 1) << 11); + bits = bits + (MIN(b, 1) << 11); } lev1 = 0; - while (MAX(a, b) >= 4) { - pki = ari_spec_lookup_fl[t + lev1 * 1024]; - *nbits = *nbits + ari_spec_bits_fl[pki][16]; + while (MAX(a, b) >= 4) + { + pki = ari_spec_lookup_fl[t + lev1 * 1024]; + bits = bits + ari_spec_bits_fl[pki][16]; - if (lev1 == 0 && mode > 0) { + if (lev1 == 0 && mode > 0) + { nbits_lsb += 2; - } else { - *nbits = *nbits + 2 * 2048; + } + else + { + bits = bits + 2 * 2048; } a = a >> 1; @@ -127,68 +197,84 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT pki = ari_spec_lookup_fl[t + lev1 * 1024]; sym = a + 4 * b; codingdata[2] = sym; - codingdata += 3; - *nbits = *nbits + ari_spec_bits_fl[pki][sym]; + codingdata += 3; + bits = bits + ari_spec_bits_fl[pki][sym]; - if (mode > 0) { + if (mode > 0) + { a1_msb = abs(xq[k]); b1_msb = abs(xq[k + 1]); - if (lev1 > 0) { + if (lev1 > 0) + { a1_msb = a1_msb >> 1; b1_msb = b1_msb >> 1; - if (a1_msb == 0 && xq[k] != 0) { + if (a1_msb == 0 && xq[k] != 0) + { nbits_lsb++; } - if (b1_msb == 0 && xq[k + 1] != 0) { + if (b1_msb == 0 && xq[k + 1] != 0) + { nbits_lsb++; } } - *nbits = *nbits + MIN(a1_msb, 1) * 2048; - *nbits = *nbits + MIN(b1_msb, 1) * 2048; + bits = bits + (MIN(a1_msb, 1) << 11); + bits = bits + (MIN(b1_msb, 1) << 11); } - if (mode >= 0 && (abs(xq[k]) != 0 || abs(xq[k + 1]) != 0) && *nbits <= target * 2048) { + if (mode >= 0 && (abs(xq[k]) != 0 || abs(xq[k + 1]) != 0) && bits <= target * 2048) + { lastnz2 = k + 2; - *nbits2 = *nbits; + bits2 = bits; } lev1 = lev1 - 1; - if (lev1 <= 0) { + + if (lev1 <= 0) + { t = 1 + (a + b) * (lev1 + 2); - } else { + } + else + { t = 13 + lev1; } c = (c & 15) * 16 + t; } - /* Number of bits */ - *nbits = ceil((LC3_FLOAT)*nbits / 2048.0); + *nbits = (bits + 2047) >> 11; // Exactly same as ceil((LC3_FLOAT)*nbits / 2048.0); - if (mode >= 0) { - *nbits2 = ceil((LC3_FLOAT)*nbits2 / 2048.0); - } else { + if (mode >= 0) + { + *nbits2 = (bits2 + 2047) >> 11; //ceil((LC3_FLOAT)*nbits2 / 2048.0); + } + else + { *nbits2 = *nbits; } - if (mode > 0) { - *nbits += nbits_lsb; + if (mode > 0) + { + *nbits += nbits_lsb; *nbits2 += nbits_lsb; } /* Truncation of high-frequency coefficients */ - for (i = lastnz2; i <= lastnz; i++) { + for (i = lastnz2; i <= lastnz; i++) + { xq[i] = 0; } /* Truncation of LSBs */ - if (mode > 0 && *nbits > target) { + if (mode > 0 && *nbits > target) + { *lsbMode = 1; - } else { + } + else + { *lsbMode = 0; } diff --git a/lib_lc3plus/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c index 77b50d7a13ba0dc8ffda32396bb5342b6438961d..61880dbd0943af7612b396748127b54cd2367ada 100644 --- a/lib_lc3plus/reorder_bitstream.c +++ b/lib_lc3plus/reorder_bitstream.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/resamp12k8.c b/lib_lc3plus/resamp12k8.c index 0cab5daae94fdd67d480dd8d3b2f7ef2cd55db4f..fd8caad7c03a57f5198ee189e5a2cc1dc39987f2 100644 --- a/lib_lc3plus/resamp12k8.c +++ b/lib_lc3plus/resamp12k8.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -16,15 +16,13 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 { - LC3_INT len_12k8 = 0, N12k8 = 0, i = 0, k = 0; - LC3_FLOAT mac = 0, buf_out[120 + MAX_LEN] = {0}, bufdown[128] = {0}, buf[120 + MAX_LEN] = {0}; + LC3_INT len_12k8, N12k8, i, k; + LC3_FLOAT mac, bufdown[128], buf[120 + MAX_LEN]; LC3_INT32 index_int, index_frac, resamp_upfac, resamp_delay, resamp_off_int, resamp_off_frac; LC3_FLOAT u_11, u_21, u_1, u_2; - const LC3_FLOAT *filter; const LC3_FLOAT *filt_input, *filt_coeff; - switch (frame_dms) { case 25: @@ -33,6 +31,11 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 case 50: len_12k8 = LEN_12K8 / 2; break; +#ifdef CR8_G_ADD_75MS + case 75: + len_12k8 = (LEN_12K8 / 4) * 3; + break; +#endif case 100: len_12k8 = LEN_12K8; break; @@ -46,8 +49,6 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 memmove(&buf[mem_in_len], x, x_len * sizeof(LC3_FLOAT)); memmove(mem_in, &buf[x_len], mem_in_len * sizeof(LC3_FLOAT)); - - filter = lp_filter[fs_idx]; /* Upsampling & Low-pass Filtering & Downsampling */ @@ -97,11 +98,11 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 mem_50[1] = (LC3_FLOAT)u_21; /* Output Buffer */ - memmove(buf_out, mem_out, mem_out_len * sizeof(LC3_FLOAT)); + memmove(buf, mem_out, mem_out_len * sizeof(LC3_FLOAT)); - memmove(&buf_out[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); + memmove(&buf[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); - memmove(y, buf_out, (*y_len + 1) * sizeof(LC3_FLOAT)); + memmove(y, buf, (*y_len + 1) * sizeof(LC3_FLOAT)); - memmove(mem_out, &buf_out[N12k8], mem_out_len * sizeof(LC3_FLOAT)); + memmove(mem_out, &buf[N12k8], mem_out_len * sizeof(LC3_FLOAT)); } diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c index 42094d275f2a2cfb6b42b92dd0ad21f79b503fd1..bcd6637310b0e54e13b7260286b4827153250da7 100644 --- a/lib_lc3plus/residual_coding.c +++ b/lib_lc3plus/residual_coding.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -19,7 +19,7 @@ void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_I LC3_INT iter=0; LC3_FLOAT offset; LC3_INT iter_max = 1; - LC3_INT nz_idx[MAX_LEN] = {0}; + LC3_INT nz_idx[MAX_LEN]; LC3_INT N_nz = 0, idx = 0; diff --git a/lib_lc3plus/residual_decoding.c b/lib_lc3plus/residual_decoding.c index 97fd94afc35e19d43c5a7866bbffb92758cdad96..5085d999af8e6c9c40c510377c4e6b7385421d05 100644 --- a/lib_lc3plus/residual_decoding.c +++ b/lib_lc3plus/residual_decoding.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -18,7 +18,7 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec LC3_INT k = 0, n = 0; LC3_FLOAT offset1 = 0, offset2 = 0; LC3_FLOAT offset = 0; - LC3_INT nz_idx[MAX_LEN] = {0}; + LC3_INT nz_idx[MAX_LEN]; LC3_INT N_nz = 0, idx = 0; LC3_INT iter = 0, iter_max = 1; @@ -65,7 +65,7 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec break; } } - offset /= 2; + offset *= 0.5; iter ++; } } diff --git a/lib_lc3plus/setup_com_lc3.c b/lib_lc3plus/setup_com_lc3.c index 17054d1ffcfdd63015e0e169b199ae606379217f..cecbfd7762fa9b3183817bcb17ebfddc66493a55 100644 --- a/lib_lc3plus/setup_com_lc3.c +++ b/lib_lc3plus/setup_com_lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -7,8 +7,8 @@ * estoppel or otherwise. * ******************************************************************************/ -#include "functions.h" #include "options.h" +#include "functions.h" LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) { diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c index c14309720ec4e0cae213b81d64ef7b170a5b651d..517a48b4921e81ae0d653be4f6f5ce9b4a3770d2 100644 --- a/lib_lc3plus/setup_dec_lc3.c +++ b/lib_lc3plus/setup_dec_lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -19,8 +19,8 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) { - int ch = 0; - size_t size = sizeof(LC3PLUS_Dec); + int ch = 0; + size_t size = sizeof(LC3PLUS_Dec); size_t frame_len = DYN_MAX_LEN_EXT(samplerate); void *PlcAdvSetup = NULL; @@ -34,6 +34,11 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) HANDLE_IIS_FFT handle_fft_phaseecu; HANDLE_IIS_FFT handle_ifft_phaseecu; LC3_FLOAT *q_old_res; + +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT32 * plc_longterm_advc_tdc = NULL, *plc_longterm_advc_ns = NULL; + LC3_INT16 longterm_analysis_counter_max = 0, longterm_analysis_counter_max_bytebuffer = 0; +#endif for (ch = 0; ch < channels; ch++) { DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); @@ -57,6 +62,15 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); + +#ifdef CR8_A_PLC_FADEOUT_TUNING + longterm_analysis_counter_max = plc_fadeout_param_maxlen[0]; + longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[0]; + + + plc_longterm_advc_tdc = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); + plc_longterm_advc_ns = balloc(decoder, &size, sizeof(LC3_INT32) * longterm_analysis_counter_max_bytebuffer); +#endif q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); @@ -80,6 +94,14 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu; setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu; + +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->PlcAdvSetup->longterm_analysis_counter_max = longterm_analysis_counter_max; + setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = longterm_analysis_counter_max_bytebuffer; + + setup->PlcAdvSetup->plc_longterm_advc_tdc = plc_longterm_advc_tdc; + setup->PlcAdvSetup->plc_longterm_advc_ns = plc_longterm_advc_ns; +#endif setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (CODEC_FS(samplerate) * 16) / 1000; real_fft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu)); @@ -104,10 +126,12 @@ LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, L decoder->plcMeth = plc_mode; decoder->hrmode = hrmode != 0; - + +#ifndef CR8_A_PLC_FADEOUT_TUNING if (decoder->fs_idx > 4) { decoder->fs_idx = 5; } +#endif decoder->channels = channels; decoder->frame_ms = 10; decoder->frame_dms = 100; @@ -175,6 +199,21 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->yLen /= 2; decoder->bands_number = bands_number_5ms[decoder->fs_idx]; } +#ifdef CR8_G_ADD_75MS + if (decoder->frame_ms == 7.5) + { + decoder->frame_length = (decoder->frame_length >> 2) * 3; + decoder->yLen = (decoder->yLen / 4) * 3; + if (decoder->hrmode) + { + decoder->bands_number = bands_number_7_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_number = bands_number_7_5ms[decoder->fs_idx]; + } + } +# endif if (decoder->hrmode) { @@ -221,6 +260,20 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } decoder->cutoffBins = BW_cutoff_bin_all_5ms; } +#ifdef CR8_G_ADD_75MS + else if (decoder->frame_ms == 7.5) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all_7_5ms; + } +# endif decoder->n_bandsPLC = MIN(decoder->frame_length, 80); @@ -246,6 +299,19 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->n_bandsPLC = 60; } } +# ifdef CR8_G_ADD_75MS + else if (decoder->frame_ms == 7.5) + { + decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_7_5ms[decoder->fs_idx]; + + if (decoder->fs != 32000 && decoder->fs != 96000) + if (decoder->fs != 32000) + { + decoder->n_bandsPLC = 60; + } + } +# endif + assert(decoder->bands_offsetPLC); if (decoder->frame_ms == 10) { @@ -263,6 +329,13 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) decoder->imdct_laZeros = MDCT_la_zeroes_5ms[decoder->fs_idx]; decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_5ms[decoder->fs_idx]; } +#ifdef CR8_G_ADD_75MS + else if (decoder->frame_ms == 7.5) { + decoder->imdct_win = MDCT_WINS_7_5ms[decoder->hrmode][decoder->fs_idx]; + decoder->imdct_laZeros = MDCT_la_zeroes_7_5ms[decoder->fs_idx]; + decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_7_5ms[decoder->fs_idx]; + } +# endif decoder->la_zeroes = decoder->imdct_laZeros; @@ -307,6 +380,11 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) setup->PlcAdvSetup->cum_fading_fast = 1; setup->PlcAdvSetup->cum_fading_slow = 1; setup->PlcAdvSetup->cum_fflcAtten = 1; + +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->PlcAdvSetup->longterm_analysis_counter_max = plc_fadeout_param_maxlen[(decoder->frame_dms / 25) - 1]; + setup->PlcAdvSetup->longterm_analysis_counter_max_bytebuffer = plc_fadeout_param_maxbytes[(decoder->frame_dms / 25) - 1]; +#endif if (decoder->fs_idx <= 4 && decoder->frame_dms == 100) { @@ -340,6 +418,9 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient */ setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs = 0; +#ifdef CR8_A_PLC_FADEOUT_TUNING + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_nonpure_tone_flag = -1; /* nonpure tone flag, -1==new calc., 0==pure, 1==nonpure */ +#endif } } } @@ -362,6 +443,12 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) maxBytes = 375; minBytes = MIN_NBYTES; break; +#ifdef CR8_G_ADD_75MS + case 75: + maxBytes = 625; + minBytes = MIN_NBYTES; + break; +#endif case 100: maxBytes = 625; minBytes = MIN_NBYTES; @@ -406,6 +493,12 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) setup->enable_lpc_weighting = (setup->total_bits < 240); totalBits = setup->total_bits * 2 - 160; } +# ifdef CR8_G_ADD_75MS + if (decoder->frame_ms == 7.5) { + setup->enable_lpc_weighting = (setup->total_bits < 360); + totalBits = round(setup->total_bits * 10 / 7.5); + } +# endif if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0)) { setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0); diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h index 6ed0f438ea7601d9646d9c821730f1ae9c1a630f..3ae6b139772945416e5976ecd110ac34e4f35add 100644 --- a/lib_lc3plus/setup_dec_lc3.h +++ b/lib_lc3plus/setup_dec_lc3.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef SETUP_DEC_LC3_FL_H #define SETUP_DEC_LC3_FL_H +#include "options.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ @@ -49,6 +50,9 @@ typedef struct { LC3_FLOAT x_fl[MAX_LEN]; LC3_FLOAT imdct_mem[MAX_LEN]; LC3_FLOAT alpha; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + LC3_FLOAT rel_pitch_change; +#endif Dct4 dct4structImdct; diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c index 986b43d6085443e801d293370634cd30bf9c7b6d..a7c94a44e2ef669e521040986d18ccd8740f45f1 100644 --- a/lib_lc3plus/setup_enc_lc3.c +++ b/lib_lc3plus/setup_enc_lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -42,9 +42,12 @@ LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels encoder->fs_in = samplerate; encoder->fs_idx = FS2FS_IDX(encoder->fs); encoder->frame_dms = 100; + +#ifndef CR8_A_PLC_FADEOUT_TUNING if (encoder->fs_idx > 4) { encoder->fs_idx = 5; } +#endif encoder->hrmode = hrmode != 0; @@ -103,6 +106,7 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->yLen = MIN(MAX_BW, encoder->frame_length); encoder->sns_damping = 0.85; } + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; encoder->bands_number = 64; encoder->nSubdivisions = 3; @@ -140,19 +144,46 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->attdec_damping = 0.5; encoder->attdec_hangover_thresh = 2; } - else if (encoder->frame_ms == 2.5) { - encoder->la_zeroes = MDCT_la_zeroes_2_5ms[encoder->fs_idx]; +#ifdef CR8_G_ADD_75MS + else if (encoder->frame_ms == 7.5) { if (encoder->hrmode) { - encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[encoder->fs_idx]; + encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[encoder->fs_idx]; } else { - encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[encoder->fs_idx]; + encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms[encoder->fs_idx]; } - encoder->cutoffBins = BW_cutoff_bin_all_2_5ms; + encoder->la_zeroes = MDCT_la_zeroes_7_5ms[encoder->fs_idx]; + encoder->cutoffBins = BW_cutoff_bin_all_7_5ms; + encoder->attdec_nblocks = 3; + encoder->attdec_damping = 0.3; + encoder->attdec_hangover_thresh = 1; + + encoder->frame_length = (encoder->frame_length >> 2) * 3; + encoder->yLen = (encoder->yLen >> 2) * 3; + + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + if (encoder->hrmode) + { + encoder->bands_number = bands_number_7_5ms_HR[encoder->fs_idx]; + } + else + { + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + } + encoder->nSubdivisions = 3; + encoder->near_nyquist_index = encoder->bands_number - 4; + encoder->r12k8_mem_out_len = ceil(2.0 * ((LC3_FLOAT) encoder->frame_length / 2.0 - (LC3_FLOAT) encoder->la_zeroes) * 12800.0 / (LC3_FLOAT) encoder->fs - 8.0); } +#endif else if (encoder->frame_ms == 5) { + encoder->frame_length = encoder->frame_length >> 1; + encoder->yLen /= 2; + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + encoder->bands_number = bands_number_5ms[encoder->fs_idx]; + encoder->nSubdivisions = 2; + encoder->near_nyquist_index = encoder->bands_number - 3; encoder->la_zeroes = MDCT_la_zeroes_5ms[encoder->fs_idx]; if (encoder->hrmode) { @@ -164,8 +195,17 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) } encoder->cutoffBins = BW_cutoff_bin_all_5ms; } - - if (encoder->frame_ms == 2.5) { + else if (encoder->frame_ms == 2.5) { + encoder->la_zeroes = MDCT_la_zeroes_2_5ms[encoder->fs_idx]; + if (encoder->hrmode) + { + encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[encoder->fs_idx]; + } + else + { + encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[encoder->fs_idx]; + } + encoder->cutoffBins = BW_cutoff_bin_all_2_5ms; encoder->frame_length = encoder->frame_length >> 2; encoder->yLen /= 4; encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; @@ -182,22 +222,14 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->near_nyquist_index = encoder->bands_number - 2; encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2); } - - - if (encoder->frame_ms == 5) { - encoder->frame_length = encoder->frame_length >> 1; - encoder->yLen /= 2; - encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; - encoder->bands_number = bands_number_5ms[encoder->fs_idx]; - encoder->nSubdivisions = 2; - encoder->near_nyquist_index = encoder->bands_number - 3; - } for (ch = 0; ch < encoder->channels; ch++) { setup = encoder->channel_setup[ch]; setup->olpa_mem_pitch = 17; - +#ifdef CR9_F_PITCH_WIN_LEN_FIX + setup->pitch_flag = 0; +#endif if (setup->mdctStruct.mem != NULL) { mdct_free(&setup->mdctStruct); mdct_init(&setup->mdctStruct, encoder->frame_length, encoder->frame_dms, encoder->fs_idx, encoder->hrmode); @@ -219,9 +251,9 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) int ch = 0, bitsTmp = 0, minBR = 0, maxBR = 0, totalBytes = 0; LC3_INT channel_bytes = 0, max_bytes = 0; +#ifdef ENABLE_HR_MODE_FL if (encoder->hrmode) { -#ifdef ENABLE_HR_MODE_FL switch (encoder->frame_dms) { case 25: @@ -236,6 +268,14 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) else if (encoder->fs == 96000) {minBR = MIN_BR_50MS_96KHZ_HR;} else { return LC3PLUS_HRMODE_ERROR;} break; +#ifdef CR8_G_ADD_75MS + case 75: + maxBR = 500000; + if (encoder->fs == 48000) {minBR = MIN_BR_075DMS_48KHZ_HR;} + else if (encoder->fs == 96000) {minBR = MIN_BR_075DMS_96KHZ_HR;} + else {return LC3PLUS_HRMODE_ERROR;} + break; +#endif case 100: maxBR = 500000; if (encoder->fs == 48000) {minBR = MIN_BR_100MS_48KHZ_HR;} @@ -245,9 +285,9 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) default: return LC3PLUS_HRMODE_ERROR; } -#endif } else +#endif /* ENABLE_HR_MODE_FL */ { minBR = (MIN_NBYTES << 3); maxBR = MAX_BR; @@ -268,6 +308,20 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) default: break; } break; +#ifdef CR8_G_ADD_75MS + case 75: + minBR = MIN_BR_075DMS; + maxBR = MAX_BR_075DMS; + /* have additional limitations for 7.5ms */ + switch (encoder->fs_in) + { + case 8000: maxBR = MAX_BR_075DMS_NB ; break; + case 16000: maxBR = MAX_BR_075DMS_WB ; break; + case 24000: maxBR = MAX_BR_075DMS_SSWB; break; + default: break; + } + break; +#endif case 100: /* have additional limitations for 10ms */ minBR = MIN_BR_100DMS; @@ -388,6 +442,11 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) setup->targetBitsAri = setup->total_bits; setup->enable_lpc_weighting = setup->total_bits < 480; +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) { + setup->enable_lpc_weighting = setup->total_bits < 360; + } +#endif if (encoder->frame_ms == 5) { setup->enable_lpc_weighting = setup->total_bits < 240; } @@ -433,6 +492,11 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) if (encoder->frame_ms == 5) { bitsTmp = bitsTmp * 2 - 160; } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) { + bitsTmp = round(bitsTmp * 10 / 7.5); + } +#endif if (bitsTmp < 400 + (encoder->fs_idx - 1) * 80) { setup->ltpf_enable = 1; @@ -461,6 +525,14 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) encoder->sns_damping = 6881.0/32768.0; } } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) + { + if (setup->total_bits > 3*4400/4) { + encoder->sns_damping = 5898.0/32768.0; + } + } +#endif if (encoder->frame_ms == 5) { if (setup->total_bits > 4600/2) { @@ -487,6 +559,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits +=2; } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) + { + setup->regBits +=1; + } +#endif if (encoder->frame_ms == 2.5) { setup->regBits -= 6; @@ -502,6 +580,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits += 0; } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) + { + setup->regBits +=2; + } +#endif if (encoder->frame_ms == 10) { setup->regBits += 5; @@ -538,9 +622,11 @@ void update_enc_bandwidth(LC3PLUS_Enc* encoder, int bandwidth) { encoder->bandwidth = bandwidth; index = FS2FS_IDX(bandwidth); +#ifndef CR8_A_PLC_FADEOUT_TUNING if (index > 4) { index = 5; } +#endif encoder->bw_ctrl_cutoff_bin = encoder->cutoffBins[index]; } } diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h index 31f0cbeb50edfb2f21c87c29192f3539f9045401..43c29e12bcd73d3d9865fb4e706da2f724bc3d23 100644 --- a/lib_lc3plus/setup_enc_lc3.h +++ b/lib_lc3plus/setup_enc_lc3.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef SETUP_ENC_LC3_FL_H #define SETUP_ENC_LC3_FL_H +#include "options.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ @@ -22,7 +23,11 @@ typedef struct { LC3_FLOAT attdec_acc_energy; LC3_FLOAT r12k8_mem_50[2]; LC3_FLOAT r12k8_mem_in[120]; +#ifdef CR8_G_ADD_75MS + LC3_FLOAT r12k8_mem_out[44]; +#else LC3_FLOAT r12k8_mem_out[24]; +#endif LC3_FLOAT olpa_mem_s12k8[3]; LC3_FLOAT olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16]; LC3_FLOAT ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1]; @@ -44,6 +49,9 @@ typedef struct { LC3_INT tns_bits; LC3_INT targetBitsQuant; LC3_INT olpa_mem_pitch; +#ifdef CR9_F_PITCH_WIN_LEN_FIX + LC3_INT pitch_flag; +#endif LC3_INT ltpf_mem_ltpf_on; LC3_INT mem_targetBits; LC3_INT mem_specBits; diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c index 5cb041925bbcf0dc5b8a0c47f0b5d8aa07d01bd1..586fd9ef669a4449dbd204ae2ff56365ba2767e7 100644 --- a/lib_lc3plus/sns_compute_scf.c +++ b/lib_lc3plus/sns_compute_scf.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,12 +11,16 @@ #include "options.h" #include "functions.h" -void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor) +void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor, LC3_INT fs_idx) { - LC3_INT bands_number = 0, d = 0, i = 0, j = 0, n = 0, n2 = 0, n4 = 0, mapping[64] = {0}; - LC3_FLOAT tmp[64] = {0}, x_tmp1[MAX_LEN] = {0}, x_tmp2[MAX_LEN] = {0}, sum = 0, mean = 0, xl4[16] = {0}, nf = 0, xl[64] = {0}, gains_smooth[M] = {0}, ratio = 0; - LC3_FLOAT W[6] = {1.0 / 12.0, 2.0 / 12.0, 3.0 / 12.0, 3.0 / 12.0, 2.0 / 12.0, 1.0 / 12.0}; - + LC3_INT bands_number, d, i, j, n, n2, n4, mapping[64]; + LC3_FLOAT x_tmp1[MAX_LEN], sum, mean, nf, gains_smooth[M], ratio; + LC3_FLOAT sum_gains_smooth; + const LC3_FLOAT* sns_preemph; + + sum_gains_smooth = 0; sum = 0; + sns_preemph = sns_preemph_all[fs_idx]; + bands_number = xLen; assert(bands_number <= 64); @@ -28,13 +32,14 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT { j = 0; for (i = 0; i < 2 * d; i = i + 2) { - tmp[i] = x[j]; - tmp[i + 1] = x[j]; + x_tmp1[i] = x[j]; + x_tmp1[i + 1] = x[j]; j++; } - move_float(&tmp[2 * d], &x[d], 64 - 2 * d); - } else if (ceil(64.0 / (LC3_FLOAT) xLen) == 4) + move_float(&x_tmp1[2 * d], &x[d], 64 - 2 * d); + } + else if (bands_number < 32) { ratio = LC3_FABS((LC3_FLOAT) (1.0 - 32.0 / (LC3_FLOAT) xLen)); n4 = round(ratio * xLen); @@ -60,13 +65,13 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT for (i = 0; i < 64; i++) { - tmp[i] = x[mapping[i] - 1]; + x_tmp1[i] = x[mapping[i] - 1]; } } else { assert(0 && "Unsupported number of bands!"); } - move_float(x, tmp, 64); + move_float(x, x_tmp1, 64); bands_number = 64; xLen = bands_number; @@ -76,20 +81,17 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT /* Smoothing */ x_tmp1[0] = x[0]; + move_float(&x_tmp1[1], &x[0], 63); - move_float(&x_tmp1[1], &x[0], xLen - 1); - - move_float(&x_tmp2[0], &x[1], xLen - 1); - - x_tmp2[xLen - 1] = x[xLen - 1]; - - for (i = 0; i < xLen; i++) { - x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x_tmp2[i]); + for (i = 0; i < 63; i++) { + x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x[i + 1]); } + + x[63] = 0.5 * x[63] + 0.25 * (x_tmp1[63] + x[63]); /* Pre-emphasis */ - for (i = 0; i < xLen; i++) { - x[i] = x[i] * LC3_POW(10.0, (LC3_FLOAT)i * (LC3_FLOAT)tilt / ((LC3_FLOAT)bands_number - 1.0) / 10.0); + for (i = 0; i < 64; i++) { + x[i] = x[i] * sns_preemph[i]; } /* Noise floor at -40dB */ @@ -97,10 +99,10 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT sum += x[i]; } - mean = sum / (LC3_FLOAT)xLen; + mean = sum * 0.015625; /* 1/64 */ - nf = mean * LC3_POW(10.0, -40.0 / 10.0); - nf = MAX(nf, LC3_POW(2.0, -32.0)); + nf = mean * 1.00e-04; + nf = MAX(nf, 2.328306436538696e-10); for (i = 0; i < 64; i++) { if (x[i] < nf) { @@ -110,45 +112,40 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT /* Log-domain */ for (i = 0; i < 64; i++) { - xl[i] = LC3_LOGTWO(x[i]) / 2.0; + x[i] = LC3_LOGTWO(x[i]) * 0.5; } /* Downsampling */ - for (n = 0; n < bands_number / 4; n++) { + for (n = 0; n < 16; n++) { if (n == 0) { - tmp[0] = xl[0]; + x_tmp1[0] = x[0]; - move_float(&tmp[1], &xl[0], 5); + move_float(&x_tmp1[1], &x[0], 5); - } else if (n == (bands_number / 4 - 1)) { - move_float(tmp, &xl[59], 5); + } else if (n == 15) { + move_float(x_tmp1, &x[59], 5); - tmp[5] = xl[63]; + x_tmp1[5] = x[63]; } else { - move_float(tmp, &xl[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1)); + move_float(x_tmp1, &x[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1)); } sum = 0; for (i = 0; i < 6; i++) { - sum += tmp[i] * W[i]; + sum += x_tmp1[i] * sns_W[i]; } - xl4[n] = sum; + gains_smooth[n] = sum; + sum_gains_smooth += sum; } /* Remove mean and scaling */ + mean = sum_gains_smooth / 16.0; - sum = 0; - for (i = 0; i < bands_number / 4; i++) { - sum += xl4[i]; - } - - mean = sum / ((LC3_FLOAT)bands_number / 4.0); - - for (i = 0; i < bands_number / 4; i++) { - gains[i] = sns_damping * (xl4[i] - mean); + for (i = 0; i < 16; i++) { + gains[i] = sns_damping * (gains_smooth[i] - mean); } /* Smoothing */ diff --git a/lib_lc3plus/sns_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c index 4419397890d890f097d538b3ee4799ca1a14c7b9..fea81e6be5684a180452a10b23d02e5a759a6dd4 100644 --- a/lib_lc3plus/sns_interpolate_scf.c +++ b/lib_lc3plus/sns_interpolate_scf.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,23 +13,23 @@ void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) { - LC3_INT i = 0, n = 0, d = 0, n4 = 0; - LC3_FLOAT tmp[MAX_BANDS_NUMBER_PLC] = {0}, ratio = 0; + LC3_INT i, n, d, n4; + LC3_FLOAT tmp[MAX_BANDS_NUMBER_PLC], ratio; /* Interpolation */ gains_int[0] = gains[0]; gains_int[1] = gains[0]; - for (n = 0; n <= 14; n++) { - gains_int[n * 4 + 2] = gains[n] + (gains[n + 1] - gains[n]) / 8.0; - gains_int[n * 4 + 3] = gains[n] + 3.0 * (gains[n + 1] - gains[n]) / 8.0; - gains_int[n * 4 + 4] = gains[n] + 5.0 * (gains[n + 1] - gains[n]) / 8.0; - gains_int[n * 4 + 5] = gains[n] + 7.0 * (gains[n + 1] - gains[n]) / 8.0; + for (n = 0; n <= 14; n++) { + gains_int[n * 4 + 2] = gains[n] + (gains[n + 1] - gains[n]) * 0.125; + gains_int[n * 4 + 3] = gains[n] + (gains[n + 1] - gains[n]) * 0.375; + gains_int[n * 4 + 4] = gains[n] + (gains[n + 1] - gains[n]) * 0.625; + gains_int[n * 4 + 5] = gains[n] + (gains[n + 1] - gains[n]) * 0.875; } - gains_int[62] = gains[15] + (gains[15] - gains[14]) / 8.0; - gains_int[63] = gains[15] + 3.0 * (gains[15] - gains[14]) / 8.0; + gains_int[62] = gains[15] + (gains[15] - gains[14]) * 0.125; + gains_int[63] = gains[15] + (gains[15] - gains[14]) * 0.375; /* For 5ms */ @@ -53,7 +53,8 @@ void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT } move_float(gains_int, tmp, d); - } else if (ceil(64.0 / (LC3_FLOAT) bands_number) == 4) + } + else if (bands_number < 32) { ratio = LC3_FABS((LC3_FLOAT) ((LC3_FLOAT)1.0 - (LC3_FLOAT)32.0 / (LC3_FLOAT) bands_number)); n4 = LC3_ROUND(ratio * (LC3_FLOAT)bands_number); diff --git a/lib_lc3plus/sns_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c index 704127cce71fdab61027a76f66f9382859048ed4..3cb81aee9ce1c85bb87827f242976cc02aa62d89 100644 --- a/lib_lc3plus/sns_quantize_scf.c +++ b/lib_lc3plus/sns_quantize_scf.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -421,7 +421,7 @@ LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len) void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses) { - LC3_INT leading_sign = 0, idx = 0, k_delta = 0, pos = 0; + LC3_INT leading_sign, idx, k_delta = 0, pos; leading_sign = 1 - 2 * LS_ind; @@ -454,9 +454,9 @@ void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pu void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) { - LC3_INT i = 0, submode = 0; + LC3_INT i, submode; LC3_INT pulses2[6] = {0}, pulses[M] = {0}; - LC3_FLOAT st2_vector[M] = {0}, st2_vector_idct[M] = {0}, sum = 0; + LC3_FLOAT st2_vector[M], st2_vector_idct[M], sum = 0; /* Decode first stage */ @@ -505,13 +505,18 @@ void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) idct_II(st2_vector, st2_vector_idct, M); /* Gain */ + /* Add stage 1 and stage 2 */ +#ifdef CR9_SIMPLIFY_LOOP + for (i = 0; i < M; i++) { + scf_q[i] += st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; + } +#else for (i = 0; i < M; i++) { st2_vector_idct[i] = st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; } - /* Add stage 1 and stage 2 */ - for (i = 0; i < M; i++) { scf_q[i] = scf_q[i] + st2_vector_idct[i]; } +#endif } diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h index fea377da412ed0c7c1df662d74537495d911353c..e311824b7fcf58b8c2363cb4bf9bfde23aa7494e 100644 --- a/lib_lc3plus/structs.h +++ b/lib_lc3plus/structs.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef STRUCTS_H #define STRUCTS_H +#include "options.h" #include "defines.h" #include "fft/iisfft.h" @@ -66,6 +67,7 @@ typedef struct { LC3_INT32 pc_be_bp_left; LC3_INT32 pc_be_bp_right; LC3_INT32 pc_return; + LC3_INT16 pc_inv_bin; } Decoder_State_fl; typedef struct { @@ -154,6 +156,9 @@ typedef struct { LC3_INT32 PhECU_num_plocs; HANDLE_IIS_FFT handle_fft_phaseecu; HANDLE_IIS_FFT handle_ifft_phaseecu; +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT16 PhECU_nonpure_tone_flag; /* BASOP Word16 PhECU_nonpure_tone_flag*/ +#endif } PlcPhEcuSetup; @@ -179,8 +184,24 @@ typedef struct { LC3_FLOAT cum_fflcAtten; LC3_FLOAT scf_q_old[M]; LC3_FLOAT scf_q_old_old[M]; - PlcPhEcuSetup PlcPhEcuSetup; + PlcPhEcuSetup PlcPhEcuSetup; + +#ifdef CR8_A_PLC_FADEOUT_TUNING + LC3_INT16 longterm_counter_plcTdc; +# ifndef CR9_L_RETRAIN_FADEOUT_TYPE_CLASSIFIER + LC3_INT16 longterm_counter_plcPhaseEcu; +# endif + LC3_INT16 longterm_counter_plcNsAdv; + LC3_INT16 longterm_analysis_counter_max; /* Maximum longterm frames number */ + LC3_INT16 longterm_analysis_counter_max_bytebuffer; /* Same as above but reduced for circular bit-buffer */ + LC3_INT32 *plc_longterm_advc_tdc; + LC3_INT32 *plc_longterm_advc_ns; + LC3_UINT8 plc_fadeout_type; + LC3_UINT8 plc_fadeout_type_first; + LC3_INT16 overall_counter; + LC3_INT8 longterm_counter_byte_position; + LC3_INT8 longterm_counter_bit_position; +#endif } PlcAdvSetup; - #endif diff --git a/lib_lc3plus/tns_coder.c b/lib_lc3plus/tns_coder.c index ff3883d2b5fa964a7a2c4a4523757432d080a5cb..e9301af9df8187d51317e49da9372a78cd6fa4bb 100644 --- a/lib_lc3plus/tns_coder.c +++ b/lib_lc3plus/tns_coder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -14,35 +14,22 @@ static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); static void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len); static void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len); -static LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue); void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen) { - LC3_INT i = 0, m = 0; - LC3_FLOAT sum = 0, tmp_buf[MAX_LEN] = {0}; + LC3_INT32 m; - for (m = -lag; m <= lag; m++) { - /* Append zeros and input vector */ - zero_float(tmp_buf, abs(m)); - - move_float(&tmp_buf[abs(m)], in, inLen - abs(m)); - - /* Calculate sum */ - sum = 0; - - for (i = 0; i < inLen; i++) { - sum += in[i] * tmp_buf[i]; - } - - out[m + lag] = sum; + for (m = 0; m <= lag; m++) { + /* Calculate correlation */ + out[m] = mac_loop(in, &in[m], (inLen - m)); } } void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len) { - LC3_INT t = 0, i = 0, j = 0; - LC3_FLOAT g = 0, v = 0, sum = 0, buf_tmp[MAX_LEN] = {0}; + LC3_INT t, i, j; + LC3_FLOAT g, v, sum, buf_tmp[10]; g = r[1] / r[0]; out_lev[0] = g; @@ -51,7 +38,6 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO rc_unq[0] = -g; for (t = 1; t < len; t++) { - zero_float(buf_tmp, len + 1); sum = 0; for (i = 1; i <= t; i++) { @@ -91,33 +77,33 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len) { - LC3_INT i = 0, j = 0; - LC3_FLOAT tmp_buf[8] = {0}, tmp_buf1[8] = {0}, tmp_buf2[8] = {0}, knxt = 0; + LC3_INT32 i, j; + LC3_FLOAT tmp_buf[8], knxt; + LC3_FLOAT norm; + memset(tmp_buf, 0, 8 * sizeof(LC3_FLOAT)); /* Initial length = 9 */ /* Drop the leading 1 */ - move_float(&tmp_buf[0], &anxt[1], (*len - 1)); - *len = *len - 1; /* Lenght = 8 */ /* Last coefficient */ - knxt = tmp_buf[*len - 1]; /* At [7] */ + knxt = anxt[*len]; /* At [7] */ *len = *len - 1; /* Lenght = 7 */ - move_float(tmp_buf1, tmp_buf, *len); - j = 0; for (i = *len - 1; i >= 0; i--) { - tmp_buf2[j] = knxt * tmp_buf[i]; + tmp_buf[j] = knxt * anxt[i + 1]; j++; } + + norm = 1.0 / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt))); out_a[0] = 1; for (i = 0; i < *len; i++) { - out_a[i + 1] = (tmp_buf1[i] - tmp_buf2[i]) / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt))); + out_a[i + 1] = (anxt[i + 1] - tmp_buf[i]) * norm; } *len = *len + 1; /* Length = 8 */ @@ -125,8 +111,8 @@ void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len) void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) { - LC3_INT k = 0, i = 0, len_old = 0; - LC3_FLOAT buf[9] = {0}; + LC3_INT k, i, len_old; + LC3_FLOAT buf[9]; len_old = len; @@ -155,30 +141,21 @@ void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) } } -LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue) -{ - LC3_INT i = 0, ret = 0; - - for (i = 0; i < 17; i++) { - if (checkValue <= in1[i] && checkValue > in2[i]) { - ret = i; - } - } - - return ret; -} void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out , LC3_INT16 near_nyquist_flag ) { - LC3_INT i = 0, stopfreq[2] = {0}, startfreq[2] = {0}, f = 0, numfilters = 0, maxOrder = 0, bits = 0, sub = 0, - subdiv_startfreq = 0, subdiv_stopfreq = 0, j = 0, rc_idx_tmp[8] = {0}, order_tmp[8] = {0}, tmp = 0, tns = 0; - LC3_FLOAT minPGfac = 0, minPredictionGain = 0, maxPG = 0, xcorr_out[MAX_LEN] = {0}, buf_tmp[MAX_LEN] = {0}, sum = 0, - subdiv_len = 0, nSubdivisions = 0, r[9] = {0}, out_lev[9] = {0}, rc_unq[9] = {0}, error_lev = 0, predGain = 0, - alpha = 0, rc[8] = {0}, st[9] = {0}, s = 0, tmpSave = 0, tmp_fl = 0; + LC3_INT i, stopfreq[2], startfreq[2], f, numfilters, maxOrder, bits, sub, + subdiv_startfreq, subdiv_stopfreq, j, rc_idx_tmp[MAXLAG], order_tmp, tmp, tns; + LC3_FLOAT minPGfac, minPredictionGain, maxPG, xcorr_out[MAXLAG + 1], sum, + subdiv_len, nSubdivisions, r[MAXLAG + 1], rc_unq[MAXLAG + 1], error_lev, predGain, + alpha, rc[MAXLAG], st[MAXLAG + 1] = {0}, s, tmpSave, tmp_fl; const LC3_INT* order; + LC3_FLOAT inv_sum, x_val; + LC3_FLOAT alpha_loc; + LC3_INT32 iIndex; /* Init */ @@ -188,8 +165,10 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L numfilters = 1; } - if (N > 40 * ((LC3_FLOAT) (frame_dms) / 10.0)) { - N = 40 * ((LC3_FLOAT) (frame_dms) / 10.0); + /* 40 * frame_dms / 10 = 4 * frame_dms */ + if (N > 4 * frame_dms) + { + N = 4 * frame_dms; fs = 40000; } @@ -213,21 +192,21 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L maxOrder = 4; nSubdivisions = 2.0; break; +#ifdef CR8_G_ADD_75MS + case 75: + maxOrder = 8; + nSubdivisions = 3; + break; +#endif case 100: maxOrder = 8; nSubdivisions = 3.0; break; } - minPGfac = 0.85; - maxPG = 2; minPredictionGain = 1.5; - if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { - maxPG = minPredictionGain; - } - - if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { + if (nBits >= 4.8 * frame_dms) { order = order1_tns; } else { order = order2_tns; @@ -249,32 +228,53 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L for (f = 0; f < numfilters; f++) { subdiv_len = ((LC3_FLOAT)stopfreq[f] + 1.0 - (LC3_FLOAT)startfreq[f]) / nSubdivisions; - zero_float(r, 9); + zero_float(r, MAXLAG+1); for (sub = 1; sub <= nSubdivisions; sub++) { subdiv_startfreq = floor(subdiv_len * (sub - 1)) + startfreq[f] - 1; subdiv_stopfreq = floor(subdiv_len * sub) + startfreq[f] - 1; + +#ifdef CR8_G_ADD_75MS + if (fs == 32000 && frame_dms == 75) + { + if (subdiv_startfreq == 83) + { + subdiv_startfreq = 82; + } + + if (subdiv_stopfreq == 83) + { + subdiv_stopfreq = 82; + } + + if (subdiv_startfreq == 160) + { + subdiv_startfreq = 159; + } + + if (subdiv_stopfreq == 160) + { + subdiv_stopfreq = 159; + } + } +#endif sum = 0; for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) { sum += x[i] * x[i]; } - if (sum < LC3_EPS) - { - zero_float(r, 9); + if (sum < LC3_EPS) { + zero_float(r, MAXLAG+1); r[0] = 1; break; } - move_float(buf_tmp, &x[subdiv_startfreq], subdiv_stopfreq - subdiv_startfreq); - - xcorr(buf_tmp, xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); + xcorr(&x[subdiv_startfreq], xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); - j = 0; - for (i = maxOrder; i >= 0; i--) { - r[j] = r[j] + xcorr_out[i] / sum; - j++; + inv_sum = 1.0 / sum; + for (i = 0; i <= maxOrder; i++) { + r[i] = r[i] + xcorr_out[i] * inv_sum; } } @@ -282,7 +282,7 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L r[i] = r[i] * lagw_tns[i]; } - levinsonDurbin(r, out_lev, rc_unq, &error_lev, maxOrder); + levinsonDurbin(r, xcorr_out, rc_unq, &error_lev, maxOrder); predGain = r[0] / error_lev; @@ -295,34 +295,50 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L bits++; if (tns == 1) { + minPGfac = 0.85; + maxPG = 2; + if (nBits >= 4.8 * frame_dms) { + maxPG = minPredictionGain; + } + /* LPC weighting */ if (predGain < maxPG) { alpha = (maxPG - predGain) * (minPGfac - 1.0) / (maxPG - minPredictionGain) + 1.0; + alpha_loc = 1; for (i = 0; i <= maxOrder; i++) { - out_lev[i] = out_lev[i] * LC3_POW(alpha, i); + xcorr_out[i] = xcorr_out[i] * alpha_loc; + alpha_loc *= alpha; } - poly2rc(out_lev, rc_unq, maxOrder + 1); + poly2rc(xcorr_out, rc_unq, maxOrder + 1); } /* PARCOR Quantization */ - for (i = 0; i < maxOrder; i++) { - rc_idx_tmp[i] = findRC_idx(&quants_thr_tns[1], &quants_thr_tns[0], rc_unq[i]); + for (i = 0; i < maxOrder; i++) + { + iIndex = 1; + x_val = rc_unq[i]; + + while ((iIndex < 17) && (x_val > quants_thr_tns[iIndex - 1])) + { + iIndex = (iIndex + 1); + } + rc_idx_tmp[i] = (iIndex - 2); } /* Filter Order */ - j = 0; + order_tmp = 0; for (i = 0; i < maxOrder; i++) { rc[i] = quants_pts_tns[rc_idx_tmp[i]]; if (rc[i] != 0) { - order_tmp[j] = i + 1; - j++; + order_tmp = i + 1; } } - order_out[f] = order_tmp[j - 1]; + order_out[f] = order_tmp; + // Disable TNS if order is 0: if (order_out[f] == 0) { tns = 0; @@ -344,6 +360,9 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L rc_idx[i] = rc_idx_tmp[j]; j++; } + } else { +tns_disabled: + order_out[f] = 0; } /* Filtering */ @@ -367,7 +386,6 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L } } } -tns_disabled: *tns_numfilters = numfilters; *bits_out = bits; diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c index d3aeefc3a379a224273e7cc7b7be1eee545af774..f4dff52f396f21d5ec260d04fafa062aa4d6cb1b 100644 --- a/lib_lc3plus/tns_decoder.c +++ b/lib_lc3plus/tns_decoder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -13,8 +13,9 @@ void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) { - LC3_INT startfreq[2] = {0}, stopfreq[2] = {0}, f = 0, i = 0, j = 0, m = 0, l = 0, rc_idx_f[9] = {0}; - LC3_FLOAT rc[9] = {0}, s = 0, st[9] = {0}; + LC3_INT startfreq[2], stopfreq[2], f, i, j, m, l; + LC3_FLOAT rc[9], s, st[9] = {0}; + LC3_INT order_tmp; if (numfilters == 2) { startfreq[0] = floor(600 * N * 2 / fs) + 1; @@ -27,19 +28,20 @@ void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT } for (f = 0; f < numfilters; f++) { - if (order[f] > 0) { + order_tmp = order[f]; + + if (order_tmp > 0) { j = 0; - for (i = f * 8; i < f * 8 + 8; i++) { - rc_idx_f[j] = rc_idx[i]; - rc[j] = quants_pts_tns[rc_idx_f[j]]; + for (i = f * 8; i < f * 8 + order_tmp; i++) { + rc[j] = quants_pts_tns[rc_idx[i]]; j++; } for (m = startfreq[f]; m <= stopfreq[f]; m++) { - s = x[m - 1] - rc[order[f] - 1] * st[order[f] - 1]; + s = x[m - 1] - rc[order_tmp - 1] * st[order_tmp - 1]; - for (l = order[f] - 2; l >= 0; l--) { + for (l = order_tmp - 2; l >= 0; l--) { s = s - rc[l] * st[l]; st[l + 1] = rc[l] * s + st[l]; } diff --git a/lib_lc3plus/util.h b/lib_lc3plus/util.h index 7ef6dedef7600c79a45549dabb1c4cf4d2d37f7f..adf422cff6b354906980aa1c271814cf25fa36bf 100644 --- a/lib_lc3plus/util.h +++ b/lib_lc3plus/util.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,7 @@ #ifndef UTIL_H #define UTIL_H +#include "options.h" #include "clib.h" #include "math.h" @@ -51,18 +52,50 @@ static inline LC3_FLOAT sqrf(LC3_FLOAT x) { return x * x; } /* convenience wrappers around memmove */ static inline void move_float(LC3_FLOAT *dst, const LC3_FLOAT *src, LC3_INT len) { +#ifdef WMOPS + LC3_INT i; + for (i = 0; i < len; i++) + { + dst[i] = src[i]; + } +#else memmove(dst, src, len * sizeof(LC3_FLOAT)); +#endif } static inline void move_int(LC3_INT *dst, const LC3_INT *src, LC3_INT len) { +#ifdef WMOPS + LC3_INT i; + for (i = 0; i < len; i++) + { + dst[i] = src[i]; + } +#else memmove(dst, src, len * sizeof(LC3_INT)); +#endif } /* convenience wrappers around memset */ static inline void zero_float(LC3_FLOAT *x, LC3_INT len) { +#ifdef WMOPS + LC3_INT i; + for (i = 0; i < len; i++) + { + x[i] = 0; + } +#else memset(x, 0, len * sizeof(LC3_FLOAT)); +#endif } static inline void zero_int(LC3_INT *x, LC3_INT len) { +#ifdef WMOPS + LC3_INT i; + for (i = 0; i < len; i++) + { + x[i] = 0; + } +#else memset(x, 0, len * sizeof(LC3_INT)); +#endif } /* multiply float vectors element by element, in-place */ diff --git a/lib_rend/ivas_MSPred.c b/lib_rend/ivas_MSPred.c index 4dcdbbb1cf3b9fb951e30316603c15cb1548567c..3986526c45b596a094f44a1f3cb0583295ab90b0 100644 --- a/lib_rend/ivas_MSPred.c +++ b/lib_rend/ivas_MSPred.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -61,15 +61,6 @@ static int32_t _round( int32_t quantPhase( float phase ) { -#ifdef SIMPLE_PHASE - int32_t phaseQ; - if ( phase < 0.0f ) - { - phase += 2.0f * _PI_; - } - phaseQ = _round( phase * SIMPLE_PHASE_QUANT_FACTOR ); - phaseQ = ( phaseQ > SIMPLE_PHASE_MAX_VAL ? SIMPLE_PHASE_MIN_VAL : phaseQ ); -#else int32_t phaseQ; phaseQ = _round( phase * PHASE_QUANT_FACTOR ); @@ -77,83 +68,9 @@ int32_t quantPhase( { phaseQ = PHASE_MIN_VAL; } -#endif return phaseQ; } -#ifdef SIMPLE_PHASE -/*-------------------------------------------------------------------* - * Function rot_pm_pi() - * - * - *-------------------------------------------------------------------*/ - -void rot_pm_pi( - float *pr, - float *pi ) -{ - /* (-1 + j0) */ - *pr = -( *pr ); - *pi = -( *pi ); - - return; -} - - -/*-------------------------------------------------------------------* - * Function ApplyInversePredictros() - * - * - *-------------------------------------------------------------------*/ - -void rot_p_pi_2( - float *pr, - float *pi ) -{ - /* (0 + j) */ - float r = *pr; - - *pr = -( *pi ); - *pi = r; - - return; -} - -/*-------------------------------------------------------------------* - * Function rot_zero() - * - * - *-------------------------------------------------------------------*/ - -void rot_zero( - float *pr, - float *pi ) -{ - *pr = *pr; - *pi = *pi; - - return; -} - -/*-------------------------------------------------------------------* - * Function rot_m_pi_2() - * - * - *-------------------------------------------------------------------*/ - -void rot_m_pi_2( - float *pr, - float *pi ) -{ - /* (0 - j) */ - float r = *pr; - - *pr = *pi; - *pi = -r; - - return; -} -#endif /*-------------------------------------------------------------------* * Function cplxmult() @@ -233,11 +150,7 @@ int32_t quantPred( float dequantPhase( const int32_t phaseQ ) { -#ifdef SIMPLE_PHASE - return (float) phaseQ / SIMPLE_PHASE_QUANT_FACTOR; -#else return (float) phaseQ / PHASE_QUANT_FACTOR; -#endif } @@ -468,9 +381,7 @@ int32_t CountMSBits( /* Differential Coding of Phase Data*/ PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); PrepEncode( piPredCopy, piMSFlags, iNumBands ); -#ifndef SIMPLE_PHASE EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); -#endif EncodePredCoef( piPredCopy, iNumMSBands ); iBitsWritten += 1; /* iMSPredAll */ @@ -486,16 +397,12 @@ int32_t CountMSBits( iBitsWritten++; /*anyNonZero Phase*/ if ( anyNonZero ) { -#ifdef SIMPLE_PHASE - iBitsWritten += iNumMSBands * SIMPLE_PHASE_BITS; -#else iBitsWritten += PHASE_BAND0_BITS; for ( b = 1; b < iNumMSBands; b++ ) { int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; } -#endif } anyNonZero = 0; /* prediction */ for ( b = 0; b < iNumMSBands; b++ ) diff --git a/lib_rend/ivas_NoiseGen.c b/lib_rend/ivas_NoiseGen.c index 3de2370827eb70f764cb15d3a45e53b949ec3e98..846a49a7871bb43321d29d7bb331d229e8a8f0ca 100644 --- a/lib_rend/ivas_NoiseGen.c +++ b/lib_rend/ivas_NoiseGen.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_PerceptualModel.c b/lib_rend/ivas_PerceptualModel.c index 4250a4fe8911c1a52404fa7b6aab700011347fe4..7c2be648032b0638b3f8d030c9028ce5f0316399 100644 --- a/lib_rend/ivas_PerceptualModel.c +++ b/lib_rend/ivas_PerceptualModel.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_PredDecoder.c b/lib_rend/ivas_PredDecoder.c index 914435e2fef984be8510b62fefe42d5d5109bd4c..ce791e93291b12d5f4034fcf111172137040126d 100644 --- a/lib_rend/ivas_PredDecoder.c +++ b/lib_rend/ivas_PredDecoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -40,7 +40,6 @@ #include "ivas_lcld_rom_tables.h" #include "wmc_auto.h" - /*-------------------------------------------------------------------* * Function CreatePredictionDecoder() * @@ -53,6 +52,7 @@ ivas_error CreatePredictionDecoder( const int32_t iNumBlocks ) { int16_t n; + int16_t m; PredictionDecoder *psPredictionDecoder = NULL; if ( ( psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ) ) == NULL ) @@ -62,20 +62,12 @@ ivas_error CreatePredictionDecoder( psPredictionDecoder->iChannels = iChannels; psPredictionDecoder->iNumBlocks = iNumBlocks; - + psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; + psPredictionDecoder->iSubSetId = 0; if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - - if ( ( psPredictionDecoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } if ( ( psPredictionDecoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -96,16 +88,25 @@ ivas_error CreatePredictionDecoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } + if ( ( psPredictionDecoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) { - if ( ( psPredictionDecoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + psPredictionDecoder->piPredChanEnable[n] = 0; + if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( LCLD_BANDS * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + for ( m = 0; m < LCLD_BANDS; m++ ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + psPredictionDecoder->ppiPredBandEnable[n][m] = 0; } if ( ( psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) { @@ -123,6 +124,19 @@ ivas_error CreatePredictionDecoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } + if ( ( psPredictionDecoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); + } + for ( m = 0; m < LCLD_BANDS; m++ ) + { + psPredictionDecoder->ppfPredStateReal[n][m] = 0; + psPredictionDecoder->ppfPredStateImag[n][m] = 0; + } } /* pre-define these tables? */ @@ -161,21 +175,22 @@ void DeletePredictionDecoder( for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) { - free( psPredictionDecoder->ppfEstPredGain[n] ); free( psPredictionDecoder->ppiPredBandEnable[n] ); free( psPredictionDecoder->ppfA1Real[n] ); free( psPredictionDecoder->ppfA1Imag[n] ); free( psPredictionDecoder->ppiA1Mag[n] ); free( psPredictionDecoder->ppiA1Phase[n] ); + free( psPredictionDecoder->ppfPredStateReal[n] ); + free( psPredictionDecoder->ppfPredStateImag[n] ); } free( psPredictionDecoder->piPredChanEnable ); - free( psPredictionDecoder->piNumPredBands ); - free( psPredictionDecoder->ppfEstPredGain ); free( psPredictionDecoder->ppiPredBandEnable ); free( psPredictionDecoder->ppfA1Real ); free( psPredictionDecoder->ppfA1Imag ); free( psPredictionDecoder->ppiA1Mag ); free( psPredictionDecoder->ppiA1Phase ); + free( psPredictionDecoder->ppfPredStateReal ); + free( psPredictionDecoder->ppfPredStateImag ); free( psPredictionDecoder ); psPredictionDecoder = NULL; @@ -183,8 +198,6 @@ void DeletePredictionDecoder( return; } - -#define USE_TABLE_LOOKUP /*-------------------------------------------------------------------* * Function ReadPredictors() * @@ -197,31 +210,49 @@ int32_t ReadPredictors( { int16_t iBitsRead = 0; int32_t c; + int32_t b; + int16_t iNumPredBandBits = 6; + const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); + + psPredictionDecoder->iNumSubSets = ivas_split_rend_bitstream_read_int32( pBits, iSubSetBits ) + 1; + iBitsRead += iSubSetBits; + if ( psPredictionDecoder->iNumSubSets > 1 ) + { + psPredictionDecoder->iSubSetId = ivas_split_rend_bitstream_read_int32( pBits, iSubSetBits ); + iBitsRead += iSubSetBits; + iNumPredBandBits = ( psPredictionDecoder->iNumSubSets >= 4 ? 4 : 5 ); + } + else + { + psPredictionDecoder->iSubSetId = 0; + } for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { - psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; + psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); + iBitsRead += (int16_t) psPredictionDecoder->iNumSubSets; - if ( psPredictionDecoder->piPredChanEnable[c] ) + if ( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) { - int32_t b; + int32_t b0 = psPredictionDecoder->iSubSetId; + int32_t bstep = psPredictionDecoder->iNumSubSets; + int32_t iNumPredBands; - for ( b = 0; b < LCLD_BANDS; b++ ) + for ( b = b0; b < LCLD_BANDS; b += bstep ) { psPredictionDecoder->ppiPredBandEnable[c][b] = 0; } - psPredictionDecoder->piNumPredBands[c] = ivas_split_rend_bitstream_read_int32( pBits, 6 ); - iBitsRead += 6; + iNumPredBands = ivas_split_rend_bitstream_read_int32( pBits, iNumPredBandBits ); + iBitsRead += iNumPredBandBits; + iNumPredBands = iNumPredBands * psPredictionDecoder->iNumSubSets + b0; - for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) + for ( b = b0; b < iNumPredBands; b += bstep ) { psPredictionDecoder->ppiPredBandEnable[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); iBitsRead += 1; if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) { -#ifdef USE_TABLE_LOOKUP int32_t iA1Mag; int32_t iA1Phase; float fA1Real; @@ -239,46 +270,23 @@ int32_t ReadPredictors( psPredictionDecoder->ppfA1Real[c][b] = fA1Real; psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; -#else - const float fInvMagScale = M_PI / ( 2.0 * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0 ); - const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); - int32_t iA1Mag; - int32_t iA1Phase; - float fA1Mag; - float fA1Phase; - float fA1Real; - float fA1Imag; - - iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); - iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; - - iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); - iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; - iA1Phase += PRED_QUANT_FILTER_PHASE_MIN; - - psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; - psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase; - - fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); - fA1Phase = fInvPhaseScale * (float) iA1Phase; - - fA1Real = fA1Mag * cosf( fA1Phase ); - fA1Imag = fA1Mag * sinf( fA1Phase ); - - psPredictionDecoder->ppfA1Real[c][b] = fA1Real; - psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; - - /* printf("Dec %f\t%f\t%f\n",fA1Real,fA1Imag,fA1Real * fA1Real + fA1Imag * fA1Imag); */ -#endif } } } - else + } + + /* disable any inactive prediction bands */ + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + int32_t set; + for ( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) { - int16_t b; - for ( b = 0; b < LCLD_BANDS; b++ ) + if ( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) { - psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + for ( b = set; b < LCLD_BANDS; b += psPredictionDecoder->iNumSubSets ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } } } } @@ -286,14 +294,13 @@ int32_t ReadPredictors( return iBitsRead; } - /*-------------------------------------------------------------------* - * Function ApplyInversePredictros() + * Function ApplyInversePredictors() * * *-------------------------------------------------------------------*/ -void ApplyInversePredictros( +void ApplyInversePredictors( PredictionDecoder *psPredictionDecoder, float ***pppfReal, float ***pppfImag ) @@ -301,30 +308,44 @@ void ApplyInversePredictros( int32_t c; for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { - if ( psPredictionDecoder->piPredChanEnable[c] == 1 ) + if ( psPredictionDecoder->piPredChanEnable[c] > 0 ) { int32_t b; - for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) + for ( b = 0; b < LCLD_BANDS; b++ ) { if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) { int32_t n; float fA1Real; float fA1Imag; + float fPrevReal = 0.0f; + float fPrevImag = 0.0f; + int32_t iSubset = b % psPredictionDecoder->iNumSubSets; + + if ( iSubset != psPredictionDecoder->iSubSetId ) + { + fPrevReal = psPredictionDecoder->ppfPredStateReal[c][b]; + fPrevImag = psPredictionDecoder->ppfPredStateImag[c][b]; + } fA1Real = psPredictionDecoder->ppfA1Real[c][b]; fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; - for ( n = 1; n < psPredictionDecoder->iNumBlocks; n++ ) + for ( n = 0; n < psPredictionDecoder->iNumBlocks; n++ ) { float fReal; float fImag; - fReal = pppfReal[c][n][b] - fA1Real * pppfReal[c][n - 1][b] + fA1Imag * pppfImag[c][n - 1][b]; - fImag = pppfImag[c][n][b] - fA1Real * pppfImag[c][n - 1][b] - fA1Imag * pppfReal[c][n - 1][b]; + fReal = pppfReal[c][n][b] - fA1Real * fPrevReal + fA1Imag * fPrevImag; + fImag = pppfImag[c][n][b] - fA1Real * fPrevImag - fA1Imag * fPrevReal; pppfReal[c][n][b] = fReal; pppfImag[c][n][b] = fImag; + + fPrevReal = fReal; + fPrevImag = fImag; } + psPredictionDecoder->ppfPredStateReal[c][b] = fPrevReal; + psPredictionDecoder->ppfPredStateImag[c][b] = fPrevImag; } } } diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c index 804a00a6a1baac7da9b06d55efdb92b37d6ef181..50ac5524fb57bf39e81531790301d6e736a2dfa4 100644 --- a/lib_rend/ivas_PredEncoder.c +++ b/lib_rend/ivas_PredEncoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -41,6 +41,31 @@ #include "wmc_auto.h" +/*-------------------------------------------------------------------* + * Function activate_bit() + * + * + *-------------------------------------------------------------------*/ +static void activate_bit( + int32_t *state, + const int32_t bit_id ) +{ + ( *state ) |= ( 1 << bit_id ); +} + +/*-------------------------------------------------------------------* + * Function deactivate_bit() + * + * + *-------------------------------------------------------------------*/ + +static void deactivate_bit( + int32_t *state, + const int32_t bit_id ) +{ + ( *state ) &= ( ~( 1 << bit_id ) ); +} + /*-------------------------------------------------------------------* * Function CreatePredictionEncoder() * @@ -50,7 +75,9 @@ ivas_error CreatePredictionEncoder( PredictionEncoder **psPredictionEncoder_out, const int32_t iChannels, - const int32_t iNumBlocks ) + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands ) { int32_t k, n; PredictionEncoder *psPredictionEncoder = NULL; @@ -62,16 +89,20 @@ ivas_error CreatePredictionEncoder( psPredictionEncoder->iChannels = iChannels; psPredictionEncoder->iNumBlocks = iNumBlocks; - - if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * iNumBlocks ) ) == NULL ) + psPredictionEncoder->iSubSetId = 0; + psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; + psPredictionEncoder->iNumSubSets = iNumSubSets; + if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * LCLD_PRED_WIN_LEN ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - for ( n = 0; n < iNumBlocks; n++ ) + + for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) { - psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) iNumBlocks ); + psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) LCLD_PRED_WIN_LEN ); } + if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); @@ -87,70 +118,140 @@ ivas_error CreatePredictionEncoder( psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly } - if ( ( psPredictionEncoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppfEstPredBitGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->pppfInpBufReal = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + if ( ( psPredictionEncoder->pppfInpBufImag = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateRealTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImagTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { - if ( ( psPredictionEncoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppfEstPredBitGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->pppfInpBufReal[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } - if ( ( psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + if ( ( psPredictionEncoder->pppfInpBufImag[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + if ( ( psPredictionEncoder->pppfInpBufReal[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->pppfInpBufReal[n][k], LCLD_BANDS ); + set_zero( psPredictionEncoder->pppfInpBufImag[n][k], LCLD_BANDS ); + } + if ( ( psPredictionEncoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); } + if ( ( psPredictionEncoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); + + if ( ( psPredictionEncoder->ppfInpPrevReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + set_zero( psPredictionEncoder->ppfInpPrevReal[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfInpPrevImag[n], LCLD_BANDS ); + + if ( ( psPredictionEncoder->ppfPredStateRealTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImagTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); for ( k = 0; k < LCLD_BANDS; k++ ) { psPredictionEncoder->ppiPredBandEnable[n][k] = 0; - psPredictionEncoder->ppfA1Real[n][k] = 0.0; - psPredictionEncoder->ppfA1Imag[n][k] = 0.0; + psPredictionEncoder->ppfA1Real[n][k] = 0.0f; + psPredictionEncoder->ppfA1Imag[n][k] = 0.0f; } } @@ -175,23 +276,42 @@ void DeletePredictionEncoder( for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) { - free( psPredictionEncoder->ppfEstPredGain[n] ); - free( psPredictionEncoder->ppfEstPredBitGain[n] ); + int32_t k; free( psPredictionEncoder->ppiPredBandEnable[n] ); free( psPredictionEncoder->ppfA1Real[n] ); free( psPredictionEncoder->ppfA1Imag[n] ); free( psPredictionEncoder->ppiA1Mag[n] ); free( psPredictionEncoder->ppiA1Phase[n] ); + for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + free( psPredictionEncoder->pppfInpBufReal[n][k] ); + free( psPredictionEncoder->pppfInpBufImag[n][k] ); + } + free( psPredictionEncoder->pppfInpBufReal[n] ); + free( psPredictionEncoder->pppfInpBufImag[n] ); + free( psPredictionEncoder->ppfInpPrevReal[n] ); + free( psPredictionEncoder->ppfInpPrevImag[n] ); + free( psPredictionEncoder->ppfPredStateReal[n] ); + free( psPredictionEncoder->ppfPredStateImag[n] ); + free( psPredictionEncoder->ppfPredStateRealTmp[n] ); + free( psPredictionEncoder->ppfPredStateImagTmp[n] ); } free( psPredictionEncoder->piPredChanEnable ); free( psPredictionEncoder->piNumPredBands ); - free( psPredictionEncoder->ppfEstPredGain ); - free( psPredictionEncoder->ppfEstPredBitGain ); free( psPredictionEncoder->ppiPredBandEnable ); free( psPredictionEncoder->ppfA1Real ); free( psPredictionEncoder->ppfA1Imag ); free( psPredictionEncoder->ppiA1Mag ); free( psPredictionEncoder->ppiA1Phase ); + free( psPredictionEncoder->pppfInpBufReal ); + free( psPredictionEncoder->pppfInpBufImag ); + free( psPredictionEncoder->ppfInpPrevReal ); + free( psPredictionEncoder->ppfInpPrevImag ); + free( psPredictionEncoder->ppfPredStateReal ); + free( psPredictionEncoder->ppfPredStateImag ); + free( psPredictionEncoder->ppfPredStateRealTmp ); + free( psPredictionEncoder->ppfPredStateImagTmp ); + free( psPredictionEncoder ); @@ -199,30 +319,58 @@ void DeletePredictionEncoder( } -//#define USE_RXX_WINDOW - /*-------------------------------------------------------------------* * Function ComputePredictors() * * *-------------------------------------------------------------------*/ -int32_t ComputePredictors( +void ComputePredictors( PredictionEncoder *psPredictionEncoder, float ***pppfReal, float ***pppfImag ) { int32_t c; - int32_t iPredictionBits = 0; + + int32_t b0 = psPredictionEncoder->iSubSetId; + int32_t bstep = psPredictionEncoder->iNumSubSets; + int32_t iNumBlocks = psPredictionEncoder->iNumBlocks; + float ***pppfRealBuf; + float ***pppfImagBuf; + float pfEstPredBitGain[LCLD_BANDS] = { 0 }; + + if ( iNumBlocks < LCLD_PRED_WIN_LEN ) + { + pppfRealBuf = psPredictionEncoder->pppfInpBufReal; + pppfImagBuf = psPredictionEncoder->pppfInpBufImag; + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t n; + for ( n = 0; n < LCLD_PRED_WIN_LEN - iNumBlocks; n++ ) + { + mvr2r( pppfRealBuf[c][n + iNumBlocks], pppfRealBuf[c][n], LCLD_BANDS ); + mvr2r( pppfImagBuf[c][n + iNumBlocks], pppfImagBuf[c][n], LCLD_BANDS ); + } + for ( n = 0; n < iNumBlocks; n++ ) + { + mvr2r( pppfReal[c][n], pppfRealBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + mvr2r( pppfImag[c][n], pppfImagBuf[c][n + LCLD_PRED_WIN_LEN - iNumBlocks], LCLD_BANDS ); + } + } + } + else + { + pppfRealBuf = pppfReal; + pppfImagBuf = pppfImag; + } for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) { int32_t b; - psPredictionEncoder->piNumPredBands[c] = 50; - for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + psPredictionEncoder->piNumPredBands[c] = min( 50, psPredictionEncoder->iMaxNumPredBands ); + for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += bstep ) { int32_t n; - int32_t iNumBlocks; float fGain = 0.0; float fBitGain = 0.0; float *pfRxxReal; @@ -232,45 +380,22 @@ int32_t ComputePredictors( int32_t iA1Mag; int32_t iA1Phase; - iNumBlocks = psPredictionEncoder->iNumBlocks; - pfRxxReal = psPredictionEncoder->pfRxxReal; pfRxxImag = psPredictionEncoder->pfRxxImag; pfRxxReal[0] = 0.0; pfRxxImag[0] = 0.0; - for ( n = 0; n < iNumBlocks; n++ ) + for ( n = 0; n < LCLD_PRED_WIN_LEN; n++ ) { -#ifdef USE_RXX_WINDOW - float fReal; - float fImag; - fReal = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; - fImag = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; - pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); -#else - pfRxxReal[0] += ( pppfReal[c][n][b] * pppfReal[c][n][b] + pppfImag[c][n][b] * pppfImag[c][n][b] ); -#endif + pfRxxReal[0] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n][b] ); } pfRxxReal[1] = 0.0; pfRxxImag[1] = 0.0; - for ( n = 1; n < iNumBlocks; n++ ) + for ( n = 1; n < LCLD_PRED_WIN_LEN; n++ ) { -#ifdef USE_RXX_WINDOW - float fReal1; - float fImag1; - float fReal2; - float fImag2; - fReal1 = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; - fImag1 = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; - fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfReal[c][n - 1][b]; - fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImag[c][n - 1][b]; - pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); - pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); -#else - pfRxxReal[1] += ( pppfReal[c][n][b] * pppfReal[c][n - 1][b] + pppfImag[c][n][b] * pppfImag[c][n - 1][b] ); - pfRxxImag[1] += ( pppfImag[c][n][b] * pppfReal[c][n - 1][b] - pppfReal[c][n][b] * pppfImag[c][n - 1][b] ); -#endif + pfRxxReal[1] += ( pppfRealBuf[c][n][b] * pppfRealBuf[c][n - 1][b] + pppfImagBuf[c][n][b] * pppfImagBuf[c][n - 1][b] ); + pfRxxImag[1] += ( pppfImagBuf[c][n][b] * pppfRealBuf[c][n - 1][b] - pppfRealBuf[c][n][b] * pppfImagBuf[c][n - 1][b] ); } if ( pfRxxReal[0] > 1e-12f ) @@ -279,6 +404,7 @@ int32_t ComputePredictors( float fA1Phase; float fGain2; float fBitGain2; + int32_t iNumBlocksPerPredCoef = min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); @@ -292,8 +418,7 @@ int32_t ComputePredictors( /* compute these before quant */ /* Compute est coding gain based on quantized filter coefficients */ fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain = 0.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) - + fBitGain = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); fA1Mag = fMagScale * asinf( fA1Mag ); iA1Mag = (int32_t) ( fA1Mag + 0.5f ); @@ -312,26 +437,21 @@ int32_t ComputePredictors( fA1Imag = fA1Mag * sinf( fA1Phase ); fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain2 = 0.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) - + fBitGain2 = 0.65f * log2f( fGain ) * (float) ( iNumBlocksPerPredCoef ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) fGain = ( fGain < fGain2 ) ? fGain : fGain2; fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; } else { - psPredictionEncoder->ppfEstPredGain[c][b] = 0.0f; fA1Real = 0.0f; fA1Imag = 0.0f; - // iA1Real = 0; - // iA1Imag = 0; iA1Mag = 0; iA1Phase = 0; fGain = -10.0f; // Fix this } - psPredictionEncoder->ppfEstPredGain[c][b] = fGain; - psPredictionEncoder->ppfEstPredBitGain[c][b] = fBitGain; - psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0 ) ? 1 : 0; // Initial prediction enable + pfEstPredBitGain[b] = fBitGain; + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); // Initial prediction enable psPredictionEncoder->ppfA1Real[c][b] = fA1Real; psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; @@ -339,91 +459,58 @@ int32_t ComputePredictors( } { - /*int32_t iDone; - int32_t iPredBands; - - iDone = 0; - iPredBands = 30; - while(iPredBands > 0 && iDone == 0){ - int32_t b; - float fBitGain; - - fBitGain = -7.0; - for(b = 0; b < iPredBands; b ++){ - fBitGain -= 1.0; - if(psPredictionEncoder->ppiPredBandEnable[c][b] == 1){ - fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; - } - } - if(fBitGain > 0.0){ //thresh - iDone ++; - } - else{ - iPredBands --; - } - }*/ - // int32_t b; float fBestCost; int32_t iPredBands; float fBitGain; + int32_t iPredChanEnable = 0; fBestCost = 0.0; iPredBands = 0; fBitGain = -7.0; - for ( b = 0; b < 30; b++ ) + for ( b = b0; b < 50; b += bstep ) { // still getting this decision wrong! fBitGain -= 1.0; if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) { - fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; + fBitGain += pfEstPredBitGain[b]; } if ( fBitGain > fBestCost ) { fBestCost = fBitGain; iPredBands = b; + iPredChanEnable = 1; } } - // printf("%d\t%f\n",iPredBands,fBestCost); - /*if(fBestCost < 300.0){ - iPredBands = 0; - }*/ - - if ( iPredBands > 0 ) + if ( iPredChanEnable == 1 ) { - // int32_t b; - iPredictionBits += 1; - iPredictionBits += 6; - for ( b = 0; b < iPredBands; b++ ) + for ( b = iPredBands + bstep; b < LCLD_BANDS; b += bstep ) { - iPredictionBits += 1; - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) - { - iPredictionBits += ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); - } + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; } - for ( b = iPredBands; b < LCLD_BANDS; b++ ) + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); + psPredictionEncoder->piNumPredBands[c] = iPredBands + bstep; + } + else if ( iPredBands > 0 ) + { + for ( b = iPredBands; b < LCLD_BANDS; b += bstep ) { psPredictionEncoder->ppiPredBandEnable[c][b] = 0; } - psPredictionEncoder->piPredChanEnable[c] = 1; + activate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); psPredictionEncoder->piNumPredBands[c] = iPredBands; } else { - // int32_t b; - iPredictionBits += 1; - for ( b = 0; b < LCLD_BANDS; b++ ) + for ( b = b0; b < LCLD_BANDS; b += bstep ) { psPredictionEncoder->ppiPredBandEnable[c][b] = 0; } - psPredictionEncoder->piPredChanEnable[c] = 0; + deactivate_bit( &psPredictionEncoder->piPredChanEnable[c], psPredictionEncoder->iSubSetId ); psPredictionEncoder->piNumPredBands[c] = 0; } } } - - return iPredictionBits; } @@ -442,23 +529,30 @@ void ApplyForwardPredictors( for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) { int32_t b; - if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) + if ( psPredictionEncoder->piPredChanEnable[c] > 0 ) { - for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + for ( b = 0; b < LCLD_BANDS; b++ ) { if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) { int32_t n; - float fOldReal; - float fOldImag; + float fOldReal = 0.0f; + float fOldImag = 0.0f; float fA1Real; float fA1Imag; - fOldReal = pppfReal[c][0][b]; - fOldImag = pppfImag[c][0][b]; + int32_t iSubset = b % psPredictionEncoder->iNumSubSets; + if ( iSubset != psPredictionEncoder->iSubSetId ) + { + fOldReal = psPredictionEncoder->ppfInpPrevReal[c][b]; + fOldImag = psPredictionEncoder->ppfInpPrevImag[c][b]; + } + psPredictionEncoder->ppfInpPrevReal[c][b] = pppfReal[c][psPredictionEncoder->iNumBlocks - 1][b]; + psPredictionEncoder->ppfInpPrevImag[c][b] = pppfImag[c][psPredictionEncoder->iNumBlocks - 1][b]; + fA1Real = psPredictionEncoder->ppfA1Real[c][b]; fA1Imag = psPredictionEncoder->ppfA1Imag[c][b]; - for ( n = 1; n < psPredictionEncoder->iNumBlocks; n++ ) + for ( n = 0; n < psPredictionEncoder->iNumBlocks; n++ ) { float fReal; float fImag; @@ -493,19 +587,39 @@ int32_t WritePredictors( { int32_t iBitsWritten = 0; int32_t c; + int32_t iNumSubSets = psPredictionEncoder->iNumSubSets; + int32_t iSubSetId = psPredictionEncoder->iSubSetId; + int32_t iNumPredBandBits = 6; + const int16_t iSubSetBits = ( LCLD_MAX_NUM_PRED_SUBSETS > 4 ? 3 : 2 ); + + /* number of subsets */ + ivas_split_rend_bitstream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */ + iBitsWritten += iSubSetBits; + + if ( iNumSubSets > 1 ) + { + /* write current subset */ + ivas_split_rend_bitstream_write_int32( pBits, iSubSetId, iSubSetBits ); + iBitsWritten += iSubSetBits; + iNumPredBandBits = ( iNumSubSets >= 4 ? 4 : 5 ); + } for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) { int32_t b; - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], 1 ); - iBitsWritten += 1; + int32_t b0 = iSubSetId; - if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) + ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); + iBitsWritten += iNumSubSets; + + if ( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) { - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piNumPredBands[c], 6 ); - iBitsWritten += 6; + int32_t iNumPredBands = ( psPredictionEncoder->piNumPredBands[c] - b0 ) / iNumSubSets; + + ivas_split_rend_bitstream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); + iBitsWritten += iNumPredBandBits; - for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) { ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); iBitsWritten += 1; @@ -517,8 +631,10 @@ int32_t WritePredictors( iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; + ivas_split_rend_bitstream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; + ivas_split_rend_bitstream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; } diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c index edbde3cb015b554a1dad566e3bab10293a79656d..b67b8c1f757d261abe3bb53c7c2061bd32402bd9 100644 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ b/lib_rend/ivas_RMSEnvGrouping.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -275,7 +275,6 @@ static void ComputeBandEnergy( return; } - /*-------------------------------------------------------------------* * Function ComputeMergeRMS() * @@ -487,7 +486,6 @@ static float TryMerge2( return fMergedCost; } - /*-------------------------------------------------------------------* * Function ComputeGreedyGroups3() * @@ -702,7 +700,7 @@ void ComputeEnvelopeGrouping( /* Perform grouping via Greedy Merge */ /* Allows control over max groups can call using 16 if want same as previous call */ - ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, LCLD_BLOCKS_PER_FRAME ); + ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->iNumBlocks ); /* Calc Groups from Merge Results */ *piNumGroups = 0; diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec.c index a7d915cf0119f92822b07f5b79d9db038645cb6f..1b8b60f595288b70ee06bbb4582e2231763b8c13 100644 --- a/lib_rend/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 988a9ecde765f02e2944e50d87f7dd90a2b362e6..e55279c60fe8b2b0c58412ed0e708a4d1f514d5b 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -1219,11 +1219,7 @@ ivas_error ivas_rend_openMultiBinCrend( ivas_error error; #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, NULL /* hHrtfStatistics */, output_Fs, pMultiBinPoseData->num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs, pMultiBinPoseData->num_poses ) ) != IVAS_ERR_OK ) -#endif #else if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs ) ) != IVAS_ERR_OK ) #endif @@ -1248,9 +1244,7 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES HRTFS_STATISTICS_HANDLE hHrtfStatistics, -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT const int32_t output_Fs, const int16_t num_poses @@ -1398,11 +1392,7 @@ ivas_error ivas_rend_openCrend( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), hHrtfStatistics, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), inConfig, ( *pCrend )->hHrtfCrend, NULL, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1615,7 +1605,7 @@ void ivas_rend_closeCldfbRend( } ivas_binRenderer_close( &pCldfbRend->hCldfbRend ); - + ivas_binaural_hrtf_close( &pCldfbRend->hHrtfFastConv ); ivas_HRTF_fastconv_binary_close( &pCldfbRend->hHrtfFastConv ); return; diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana.c index 2391d7cfac42fc5de7d549d0b369efb067d39288..098ee9fb48442f86407b50bf3e168f18219c20c2 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index a37d55ea8e7698f69efdcbfc96813946a8967149..d3d50a6b71ea50ef91e4d3237560e76ea8198dd9 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -119,9 +119,9 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( COM static void formulate2x2MixingMatrix( float Ein1, float Ein2, float CinRe, float CinIm, float Eout1, float Eout2, float CoutRe, float CoutIm, float Q[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Mre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Mim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], const float regularizationFactor ); -static void hrtfShGetHrtf( const int16_t bin, const int16_t aziDeg, const int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t useCachedValue ); +static void hrtfShGetHrtf( const int16_t bin, const int16_t aziDeg, const int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t useCachedValue, HRTFS_PARAMBIN_HANDLE hHrtfParambin ); -static void getDirectPartGains( const int16_t bin, int16_t aziDeg, int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, const uint8_t stereoMode, float Rmat[3][3], PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t isHeadtracked ); +static void getDirectPartGains( const int16_t bin, int16_t aziDeg, int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, const uint8_t stereoMode, float Rmat[3][3], PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t isHeadtracked, HRTFS_PARAMBIN_HANDLE hHrtfParambin ); static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); @@ -140,8 +140,8 @@ static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtR *------------------------------------------------------------------------*/ ivas_error ivas_dirac_dec_init_binaural_data( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : HRTF structure for rendering */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + HRTFS_PARAMBIN_HANDLE *phHrtfParambin /* i : HRTF structure for rendering */ ) { DIRAC_DEC_BIN_HANDLE hDiracDecBin; @@ -173,6 +173,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( hDiracDecBin->hReverb = NULL; hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; + hDiracDecBin->phHrtfParambin = NULL; } output_Fs = st_ivas->hDecoderConfig->output_Fs; @@ -224,7 +225,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( } else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */ { - mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); + mvr2r( ( *phHrtfParambin )->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); /* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */ if ( hDiracDecBin->hReverb != NULL && ( ( hDiracDecBin->hReverb->numBins != nBins ) || @@ -239,12 +240,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( hDiracDecBin->hReverb == NULL ) #endif { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, st_ivas->hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( st_ivas->hRenderConfig->roomAcoustics ), output_Fs, st_ivas->hHrtfParambin->parametricReverberationTimes, st_ivas->hHrtfParambin->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) -#else - /* Todo Philips: Room acoustics should be passed here once the underlying part works. Probably enough to pick it from st_ivas but you know best. */ - if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) -#endif + if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, st_ivas->hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( st_ivas->hRenderConfig->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) { return error; } @@ -308,6 +304,8 @@ ivas_error ivas_dirac_dec_init_binaural_data( hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); + hDiracDecBin->phHrtfParambin = phHrtfParambin; + #ifdef SPLIT_REND_WITH_HEAD_ROT st_ivas->hDiracDecBin[pos_idx] = hDiracDecBin; } @@ -673,28 +671,14 @@ static void ivas_dirac_dec_binaural_internal( if ( st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ) { int16_t numCoreBands, b; -#ifndef NONBE_FIX_951_MCMASA_5MS_RENDERING - int16_t slotInFrame; -#endif numCoreBands = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->numCoreBands; -#ifndef NONBE_FIX_951_MCMASA_5MS_RENDERING - slotInFrame = hSpatParamRendCom->slots_rendered + slot; -#endif generate_masking_noise_dirac( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom, st_ivas->cldfbAnaDec[1], -#ifdef NONBE_FIX_951_MCMASA_5MS_RENDERING &st_ivas->hTcBuffer->tc[nchan_transport][hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->slots_rendered], -#else - st_ivas->hTcBuffer->tc[nchan_transport], -#endif Cldfb_RealBuffer_in[2][slot], Cldfb_ImagBuffer_in[2][slot], -#ifdef NONBE_FIX_951_MCMASA_5MS_RENDERING slot, -#else - slotInFrame, -#endif st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ); @@ -702,11 +686,7 @@ static void ivas_dirac_dec_binaural_internal( st_ivas->cldfbAnaDec[1], /*nothing will be analyzed, just get cnst*/ NULL, Cldfb_RealBuffer_in[1][slot], Cldfb_ImagBuffer_in[1][slot], -#ifdef NONBE_FIX_951_MCMASA_5MS_RENDERING slot, -#else - slotInFrame, -#endif st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ); @@ -1312,7 +1292,7 @@ static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( spreadCoh = max( spreadCoh, altSpreadCoh ); } - getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked ); + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked, *hDiracDecBin->phHrtfParambin ); if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) { @@ -1355,7 +1335,7 @@ static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( rImagp *= centerMul; /* Apply the gain for the left source of the three coherent sources */ - getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); + getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked, *hDiracDecBin->phHrtfParambin ); hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); lRealp += sidesMul * lRealpTmp; @@ -1365,7 +1345,7 @@ static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( /* Apply the gain for the right source of the three coherent sources. * -30 degrees to 330 wrapping due to internal functions. */ - getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked ); + getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked, *hDiracDecBin->phHrtfParambin ); hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); lRealp += sidesMul * lRealpTmp; lImagp += sidesMul * lImagpTmp; @@ -1754,7 +1734,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric spreadCoh = max( spreadCoh, altSpreadCoh ); } - getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked ); + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked, *hDiracDecBin->phHrtfParambin ); if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) { @@ -1797,7 +1777,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric rImagp *= centerMul; /* Apply the gain for the left source of the three coherent sources */ - getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); + getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked, *hDiracDecBin->phHrtfParambin ); hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); lRealp += sidesMul * lRealpTmp; @@ -1807,7 +1787,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Apply the gain for the right source of the three coherent sources. * -30 degrees to 330 wrapping due to internal functions. */ - getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked ); + getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked, *hDiracDecBin->phHrtfParambin ); hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); lRealp += sidesMul * lRealpTmp; lImagp += sidesMul * lImagpTmp; @@ -2161,7 +2141,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( if ( ivas_format == MASA_ISM_FORMAT ) { - gainFactor = 0.7943f * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] ); + gainFactor = OMASA_TDREND_MATCHING_GAIN * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] ); } else { @@ -2217,7 +2197,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin->processMtxImPrev[chA][chB + 2][bin] = hDiracDecBin->processMtxIm[chA][chB + 2][bin]; } - getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked ); + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked, *hDiracDecBin->phHrtfParambin ); hDiracDecBin->processMtxRe[0][chB + 2][bin] = lRealp * gainFactor; hDiracDecBin->processMtxIm[0][chB + 2][bin] = lImagp * gainFactor; @@ -2992,7 +2972,8 @@ static void getDirectPartGains( const uint8_t renderStereoOutputInsteadOfBinaural, float Rmat[3][3], PARAMBIN_HRTF_GAIN_CACHE *gainCache, - const int16_t isHeadtracked ) + const int16_t isHeadtracked, + HRTFS_PARAMBIN_HANDLE hHrtfParambin ) { float aziRad, eleRad; float y, mappedX, aziRadMapped, A, A2, A3; @@ -3037,7 +3018,7 @@ static void getDirectPartGains( { if ( aziDeg == gainCache->azi && eleDeg == gainCache->ele ) { - hrtfShGetHrtf( bin, aziDeg, eleDeg, lRealp, lImagp, rRealp, rImagp, gainCache, TRUE ); + hrtfShGetHrtf( bin, aziDeg, eleDeg, lRealp, lImagp, rRealp, rImagp, gainCache, TRUE, hHrtfParambin ); } else { @@ -3047,7 +3028,7 @@ static void getDirectPartGains( { rotateAziEle( (float) aziDeg, (float) eleDeg, &aziDeg, &eleDeg, Rmat, 0 ); } - hrtfShGetHrtf( bin, aziDeg, eleDeg, lRealp, lImagp, rRealp, rImagp, gainCache, FALSE ); + hrtfShGetHrtf( bin, aziDeg, eleDeg, lRealp, lImagp, rRealp, rImagp, gainCache, FALSE, hHrtfParambin ); } } @@ -3064,9 +3045,14 @@ static void hrtfShGetHrtf( float *rRealp, float *rImagp, PARAMBIN_HRTF_GAIN_CACHE *gainCache, - const int16_t useCachedValue ) + const int16_t useCachedValue, + HRTFS_PARAMBIN_HANDLE hHrtfParambin ) { int16_t k; + float( *hrtfShCoeffsReInt )[16][60]; + float( *hrtfShCoeffsImInt )[16][60]; + hrtfShCoeffsReInt = hHrtfParambin->hrtfShCoeffsRe; + hrtfShCoeffsImInt = hHrtfParambin->hrtfShCoeffsIm; *lRealp = 0.0f; *lImagp = 0.0f; @@ -3080,10 +3066,10 @@ static void hrtfShGetHrtf( for ( k = 0; k < HRTF_SH_CHANNELS; k++ ) { - *lRealp += hrtfShCoeffsRe[0][k][bin] * shVec[k]; - *lImagp += hrtfShCoeffsIm[0][k][bin] * shVec[k]; - *rRealp += hrtfShCoeffsRe[1][k][bin] * shVec[k]; - *rImagp += hrtfShCoeffsIm[1][k][bin] * shVec[k]; + *lRealp += hrtfShCoeffsReInt[0][k][bin] * shVec[k]; + *lImagp += hrtfShCoeffsImInt[0][k][bin] * shVec[k]; + *rRealp += hrtfShCoeffsReInt[1][k][bin] * shVec[k]; + *rImagp += hrtfShCoeffsImInt[1][k][bin] * shVec[k]; } } else @@ -3097,10 +3083,10 @@ static void hrtfShGetHrtf( for ( k = 0; k < HRTF_SH_CHANNELS; k++ ) { - *lRealp += hrtfShCoeffsRe[0][k][bin] * shVec[k]; - *lImagp += hrtfShCoeffsIm[0][k][bin] * shVec[k]; - *rRealp += hrtfShCoeffsRe[1][k][bin] * shVec[k]; - *rImagp += hrtfShCoeffsIm[1][k][bin] * shVec[k]; + *lRealp += hrtfShCoeffsReInt[0][k][bin] * shVec[k]; + *lImagp += hrtfShCoeffsImInt[0][k][bin] * shVec[k]; + *rRealp += hrtfShCoeffsReInt[1][k][bin] * shVec[k]; + *rImagp += hrtfShCoeffsImInt[1][k][bin] * shVec[k]; gainCache->shVec[k] = shVec[k]; } diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index 89c2c4a086068ac02468268de25227c6215464bc..650466eef6d48e20889daeac709bc2a295ab1a91 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_rend/ivas_dirac_onsets_dec.c index 8a03dc2c50da814c0788b1c81325e87633e0ec46..564f75521a9601f32a6da6f172110fba453c3c08 100644 --- a/lib_rend/ivas_dirac_onsets_dec.c +++ b/lib_rend/ivas_dirac_onsets_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 8ee3b1e4f588cd0f478e888a3b1b74333721b420..54ea30216527a106c7381be3fc52a28c32bb77e3 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -542,11 +542,9 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *diffuseness, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t sh_rot_max_order, - const float *p_Rmat, /* i : rotation matrix */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport, /* i : number of transport channels*/ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ + const int16_t nchan_transport, /* i : number of transport channels*/ const int16_t md_idx, const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ const int16_t dec_param_estim ) @@ -590,8 +588,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( elevation, md_idx, NULL, - 2, - p_Rmat, hodirac_flag ); } @@ -638,8 +634,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( elevation, md_idx, NULL, - sh_rot_max_order, - p_Rmat, hodirac_flag ); if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) @@ -1571,169 +1565,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( } -/*------------------------------------------------------------------------- - * ivas_dirac_dec_get_response_split_order() - * - * calculate reponse, 1 degree resolution - *------------------------------------------------------------------------*/ - -static void ivas_dirac_dec_get_response_split_order( - const int16_t azimuth, - const int16_t elevation, - float *response, - const int16_t shd_rot_max_order, - const float *p_Rmat ) -{ - int16_t index_azimuth, index_elevation; - int16_t el, e, az; - float cos_1, cos_2, sin_1, cos_az[3]; - float sin_az[3]; - float f, c; - int16_t l, m; - int16_t b, b1, b_2, b1_2, a; - float dv_0, dv_1, dv_2, dv_r_0, dv_r_1, dv_r_2; - float w; - - push_wmops( "ivas_dirac_dec_get_response_split_order" ); - - index_azimuth = ( azimuth + 180 ) % 360; - index_elevation = elevation + 90; - e = index_elevation > 90 ? -1 : 1; - el = index_elevation > 90 ? 180 - index_elevation : index_elevation; - - az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; - f = index_azimuth > 180 ? -1.0f : 1.0f; - - cos_1 = dirac_gains_trg_term[az][0]; - sin_1 = f * dirac_gains_trg_term[az][1]; - - cos_2 = cos_1 * cos_1; - - cos_az[0] = cos_1; - cos_az[1] = 2.0f * cos_2 - 1.0f; - cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; - sin_az[0] = sin_1; - sin_az[1] = sin_1 * 2.0f * cos_1; - sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); - - response[0] = 1.0f; - for ( l = 1; l <= shd_rot_max_order; l++ ) - { - b_2 = l * l; - b1_2 = l * l + 2 * l; - for ( m = 0; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - for ( m = 1; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - c = c * e; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - b = b_2 + l; - a = dirac_gains_P_idx[b]; - c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - if ( l % 2 == 1 ) - { - c = c * e; - } - - response[b] = c; - } - - /*Conversion spherical to cartesian coordinates*/ - w = -dirac_gains_trg_term[el][1]; - dv_0 = w * cos_1; - dv_1 = w * sin_1; - dv_2 = e * dirac_gains_trg_term[el][0]; - - /*Rotation mtx multiplication*/ - dv_r_0 = p_Rmat[0] * dv_0 + p_Rmat[1] * dv_1 + p_Rmat[2] * dv_2; - dv_r_1 = p_Rmat[3] * dv_0 + p_Rmat[4] * dv_1 + p_Rmat[5] * dv_2; - dv_r_2 = p_Rmat[6] * dv_0 + p_Rmat[7] * dv_1 + p_Rmat[8] * dv_2; - - index_azimuth = ( (int16_t) ( atan2f( dv_r_1, dv_r_0 ) * _180_OVER_PI ) + 180 ) % 360; - index_elevation = (int16_t) ( atan2f( dv_r_2, sqrtf( dv_r_0 * dv_r_0 + dv_r_1 * dv_r_1 ) ) * _180_OVER_PI ) + 90; - e = index_elevation > 90 ? -1 : 1; - el = index_elevation > 90 ? 180 - index_elevation : index_elevation; - - az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; - f = index_azimuth > 180 ? -1.0f : 1.0f; - - cos_1 = dirac_gains_trg_term[az][0]; - sin_1 = f * dirac_gains_trg_term[az][1]; - - cos_2 = cos_1 * cos_1; - - cos_az[0] = cos_1; - cos_az[1] = 2.0f * cos_2 - 1.0f; - cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; - sin_az[0] = sin_1; - sin_az[1] = sin_1 * 2.0f * cos_1; - sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); - - for ( l = shd_rot_max_order + 1; l <= 3; l++ ) - { - b_2 = l * l; - b1_2 = l * l + 2 * l; - for ( m = 0; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - for ( m = 1; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - c = c * e; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - b = b_2 + l; - a = dirac_gains_P_idx[b]; - c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - if ( l % 2 == 1 ) - { - c = c * e; - } - - response[b] = c; - } - - pop_wmops(); - - return; -} - - /*------------------------------------------------------------------------- * ivas_dirac_dec_compute_directional_responses() * @@ -1750,9 +1581,7 @@ void ivas_dirac_dec_compute_directional_responses( const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, - const int16_t shd_rot_max_order, /* i : split-order rotation method */ - const float *p_Rmat, /* i : rotation matrix */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ + const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ) { int16_t k, l; @@ -1822,23 +1651,11 @@ void ivas_dirac_dec_compute_directional_responses( set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS ); set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS ); - if ( p_Rmat != 0 ) - { - ivas_dirac_dec_get_response_split_order( azimuth[k], elevation[k], direct_response_hoa, shd_rot_max_order, p_Rmat ); + ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order ); - if ( hodirac_flag ) - { - ivas_dirac_dec_get_response_split_order( azimuth2[k], elevation2[k], direct_response_dir2, shd_rot_max_order, p_Rmat ); - } - } - else + if ( hodirac_flag ) { - ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order ); - - if ( hodirac_flag ) - { - ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order ); - } + ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order ); } if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 9fa1ddd8e4e32a535345742066662495495ebc2a..94982acb10c3a82da5b2b8eeb60e360f06f3471f 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -2216,8 +2216,6 @@ static void ivas_masa_ext_dirac_render_sf( elevation, md_idx, surCohRatio, - 0, - NULL, 0 ); @@ -2372,8 +2370,6 @@ static void ivas_masa_ext_dirac_render_sf( hSpatParamRendCom->diffuseness_vector[md_idx], hSpatParamRendCom, hDirACRend, - 0, - 0, hMasaExtRend->hVBAPdata, hDirACRend->hOutSetup, nchan_transport, diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 40f5e731202e300447975a2abfd3f5ee6c3ad57a..3caf13783fceb33c2dcd00f8a586084a275788f2 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf.c index ec40720466c32709d078163a8058fd8ef462ea89..95b88a0cd6f2bdc2847cb8fcb3ef6c5fa25b9760 100644 --- a/lib_rend/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -37,9 +37,7 @@ #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_prot.h" -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES #include "ivas_rom_binaural_crend_head.h" -#endif /*-----------------------------------------------------------------------* * ivas_HRTF_binary_open() @@ -214,7 +212,6 @@ void ivas_HRTF_parambin_binary_close( return; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES /*-----------------------------------------------------------------------* * ivas_HRTF_statistics_binary_open() * @@ -307,4 +304,3 @@ ivas_error ivas_HRTF_statistics_init( return IVAS_ERR_OK; } -#endif diff --git a/lib_rend/ivas_lc3plus_common.c b/lib_rend/ivas_lc3plus_common.c index db33f9861fec97e629bf2e8453cb0aefb97f6426..cc350411e9d51d3ba12763571e650992b1c12eed 100644 --- a/lib_rend/ivas_lc3plus_common.c +++ b/lib_rend/ivas_lc3plus_common.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_lc3plus_common.h b/lib_rend/ivas_lc3plus_common.h index 93a37488cc92de08c197022d4470ad8947a86fec..49657d2b2f75c5f8ff8302b0a7961fb297d535c1 100644 --- a/lib_rend/ivas_lc3plus_common.h +++ b/lib_rend/ivas_lc3plus_common.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_lc3plus_dec.c b/lib_rend/ivas_lc3plus_dec.c index 5dfdb9cec794a8127d290146a7a9a1bbc9af5acf..a5a663884a8e16e875548c669d741010959031a3 100644 --- a/lib_rend/ivas_lc3plus_dec.c +++ b/lib_rend/ivas_lc3plus_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_lc3plus_dec.h b/lib_rend/ivas_lc3plus_dec.h index 6e6f13f626ed8b3dae3920d3531d3de45f17fff6..ce4d6281045db590f0cca67ebbcc6211a8b2928c 100644 --- a/lib_rend/ivas_lc3plus_dec.h +++ b/lib_rend/ivas_lc3plus_dec.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_lc3plus_enc.c b/lib_rend/ivas_lc3plus_enc.c index 8751d3dacc061fb39e80f01bd06896ba068b57af..f81d912dc917e87c567e8a28deeb3639010e5df4 100644 --- a/lib_rend/ivas_lc3plus_enc.c +++ b/lib_rend/ivas_lc3plus_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_lc3plus_enc.h b/lib_rend/ivas_lc3plus_enc.h index d58ecf1b653deec0295e99e6dcd6550c9cd24970..a4ea7c808faf20e857e8666f5ed07c9e81036999 100644 --- a/lib_rend/ivas_lc3plus_enc.h +++ b/lib_rend/ivas_lc3plus_enc.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c index 8aafcb1fa81198c1e3307fc28b325527c977d7dd..b98b4f4e00ef2cae0f2328217b857d5e0fc11e30 100644 --- a/lib_rend/ivas_lcld_decoder.c +++ b/lib_rend/ivas_lcld_decoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -83,9 +83,6 @@ struct LCLD_DECODER uint32_t num_decode_table[2 * ALLOC_TABLE_SIZE]; int32_t piMSPredCoefs[MAX_BANDS]; int32_t piLRPhaseDiffs[MAX_BANDS]; -#ifdef ENABLE_PMOD_ADJUST - int32_t **ppiHiSMRFlags; -#endif int32_t iCommonGrouping; int32_t *piNumGroups; int32_t **ppiGroupLengths; @@ -347,26 +344,27 @@ static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const ui ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, - const int32_t iChannels ) + const int32_t iChannels, + const int32_t iNumBlocks ) { int32_t n; int32_t read_length; ivas_error error; LCLDDecoder *psLCLDDecoder = NULL; - assert( iSampleRate == 48000 ); // Fix - + assert( iSampleRate == 48000 ); + assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); if ( ( psLCLDDecoder = (LCLDDecoder *) malloc( sizeof( LCLDDecoder ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } psLCLDDecoder->iSampleRate = iSampleRate; psLCLDDecoder->iChannels = iChannels; - psLCLDDecoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; + psLCLDDecoder->iNumBlocks = iNumBlocks; psLCLDDecoder->iAllocOffset = 0; - psLCLDDecoder->iNumBands = MAX_BANDS_48; // Fix - psLCLDDecoder->piBandwidths = c_aiBandwidths48; // Fix + psLCLDDecoder->iNumBands = 0; /* read from bitstream*/ + psLCLDDecoder->piBandwidths = c_aiBandwidths48; psLCLDDecoder->iMSMode = 0; if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) @@ -378,10 +376,6 @@ ivas_error CreateLCLDDecoder( psLCLDDecoder->piLRPhaseDiffs[n] = 0; psLCLDDecoder->piMSPredCoefs[n] = 0; } -#ifdef ENABLE_PMOD_ADJUST - psLCLDDecoder->ppiHiSMRFlags = - (int32_t **) malloc( psLCLDDecoder->iChannels * sizeof( int32_t * ) ); -#endif psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ if ( ( psLCLDDecoder->piNumGroups = (int32_t *) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ) ) ) == NULL ) @@ -429,11 +423,6 @@ ivas_error CreateLCLDDecoder( for ( n = 0; n < iChannels; n++ ) { int16_t k; -#ifdef ENABLE_PMOD_ADJUST - psLCLDDecoder->ppiHiSMRFlags[n] = - (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); - ; -#endif if ( ( psLCLDDecoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -529,7 +518,7 @@ ivas_error CreateLCLDDecoder( { return error; } - psLCLDDecoder->psNoiseGen = NULL; // CreateNoiseGen(); // No noise fill for now + psLCLDDecoder->psNoiseGen = NULL; /* CreateNoiseGen(); No noise fill for now*/ *psLCLDDecoder_out = psLCLDDecoder; return IVAS_ERR_OK; @@ -606,16 +595,6 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) free( psLCLDDecoder->pppiExcitation ); } -#ifdef ENABLE_PMOD_ADJUST - if ( psLCLDDecoder->ppiHiSMRFlags != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - free( psLCLDDecoder->ppiHiSMRFlags[n] ); - } - free( psLCLDDecoder->ppiHiSMRFlags ); - } -#endif if ( psLCLDDecoder->pppiAlloc != NULL ) { @@ -717,7 +696,7 @@ void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) static void ApplyRMSEnvelope( const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iNumGroups, const int32_t *piGroupLengths, int32_t **ppiRMSEnvelope, float **ppfReal, float **ppfImag ); -static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag ); +static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag, const int32_t *piBandwidths ); static void InvQuantizeSpectrum( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag, float **ppfReal, float **ppfImag, NoiseGen *psNoiseGen ); @@ -768,9 +747,6 @@ int32_t DecodeLCLDFrame( ReadRMSEnvelope( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); -#ifdef ENABLE_PMOD_ADJUST - ReadPmodInformation( psLCLDDecoder->ppiHiSMRFlags, pBits, psLCLDDecoder->iChannels, psLCLDDecoder->iNumBands ); -#endif ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); @@ -790,7 +766,7 @@ int32_t DecodeLCLDFrame( else { for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { // This will be updated to support multiple sample rates + { /* This will be updated to support multiple sample rates*/ for ( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) { PerceptualModel( psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope[n][k], psLCLDDecoder->pppiExcitation[n][k], psLCLDDecoder->pppiSMR[n][k] ); @@ -826,13 +802,27 @@ int32_t DecodeLCLDFrame( pppfLCLDReal[n], pppfLCLDImag[n], psLCLDDecoder->psNoiseGen ); - ReplaceSign( psLCLDDecoder->iNumBlocks, LCLD_BANDS, + ReplaceSign( psLCLDDecoder->iNumBlocks, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiLCLDSignReal[n], psLCLDDecoder->pppiLCLDSignImag[n], - pppfLCLDReal[n], pppfLCLDImag[n] ); + pppfLCLDReal[n], pppfLCLDImag[n], psLCLDDecoder->piBandwidths ); + } +#ifdef DEBUG_WRITE_PREDICTORS + { + static FILE *fid; + if ( !fid ) + fid = fopen( "pred_dec.txt", "wt" ); + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + int16_t b; + for ( b = 0; b < 60; b++ ) + fprintf( fid, "%.5f ", (float) psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n][b] * psLCLDDecoder->psPredictionDecoder->ppfA1Imag[n][b] ); + } + fprintf( fid, "%d %d\n", psLCLDDecoder->psPredictionDecoder->iSubSetId, psLCLDDecoder->psPredictionDecoder->piPredChanEnable[n] ); } +#endif - ApplyInversePredictros( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); + ApplyInversePredictors( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) { @@ -904,29 +894,35 @@ static void ApplyRMSEnvelope( return; } - static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, - float **ppfImag ) + float **ppfImag, + const int32_t *piBandwidths ) { int32_t b, n; + int32_t m, idx; for ( n = 0; n < iNumBlocks; n++ ) { + idx = 0; for ( b = 0; b < iNumLCLDBands; b++ ) { - if ( ppiSignReal[n][b] == 1 ) + for ( m = 0; m < piBandwidths[b]; m++ ) { - ppfReal[n][b] = -ppfReal[n][b]; - } + if ( ppiSignReal[n][idx] == 1 ) + { + ppfReal[n][idx] = -ppfReal[n][idx]; + } - if ( ppiSignImag[n][b] == 1 ) - { - ppfImag[n][b] = -ppfImag[n][b]; + if ( ppiSignImag[n][idx] == 1 ) + { + ppfImag[n][idx] = -ppfImag[n][idx]; + } + idx++; } } } @@ -1020,10 +1016,7 @@ static void InvMSCoding( { int32_t b; int32_t iFBOffset; - int32_t bms = 0; -#if defined SIMPLE_PHASE - void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_m_pi_2, &rot_pm_pi, &rot_p_pi_2 }; -#endif + int32_t bMSPred = 0; iFBOffset = 0; for ( b = 0; b < iNumBands; b++ ) @@ -1031,10 +1024,10 @@ static void InvMSCoding( if ( piMSFlags[b] == 1 ) { int32_t n; -#if defined SIMPLE_PHASE - void ( *pFuncPhaseRotate )( float *, float * ) = - pFuncPhaseRotateOptions[piLRPhaseDiffs[bms]]; -#endif + int32_t phaseIdx; + float fPred; + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; + fPred = dequantPred( piMSPredCoefs[bMSPred] ); for ( n = 0; n < piBandwidths[b]; n++ ) { int32_t k; @@ -1047,8 +1040,6 @@ static void InvMSCoding( if ( iMSMode == 3 ) { - float fPred; - fPred = dequantPred( piMSPredCoefs[bms] ); pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; } @@ -1060,13 +1051,7 @@ static void InvMSCoding( if ( iMSMode == 3 ) { -#ifdef SIMPLE_PHASE - ( *pFuncPhaseRotate )( &fRightReal, &fRightImag ); -#else - int32_t phaseIdx; - phaseIdx = piLRPhaseDiffs[bms] - PHASE_MIN_VAL; cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); -#endif } pppfReal[0][k][iFBOffset] = fLeftReal; @@ -1076,8 +1061,7 @@ static void InvMSCoding( } iFBOffset++; } - - bms++; + bMSPred++; } else { @@ -1175,13 +1159,6 @@ static int32_t ReadMSInformation( anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); if ( anyNonZero ) { -#ifdef SIMPLE_PHASE - for ( n = 0; n < iNumMSPredBands; n++ ) - { - piLRPhaseDiffs[n] = ivas_split_rend_bitstream_read_int32( pBits, SIMPLE_PHASE_BITS ); - iBitsRead += SIMPLE_PHASE_BITS; - } -#else piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS ); piLRPhaseDiffs[0] += PHASE_MIN_VAL; iBitsRead += PHASE_BAND0_BITS; @@ -1192,7 +1169,6 @@ static int32_t ReadMSInformation( piLRPhaseDiffs[n] = tabIdx + ENV_DELTA_MIN; } DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); -#endif } else { @@ -1224,11 +1200,9 @@ static int32_t ReadMSInformation( } #ifdef DEBUG_WRITE_MS_PRED { - static FILE *fid = 0; + static FILE *fid; if ( !fid ) - { - fid = fopen( "ms_mode_dec.txt", "wt" ); - } + fid = fopen( "ms_pred_dec.txt", "wt" ); writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); } #endif @@ -1241,7 +1215,6 @@ static int32_t ReadMSInformation( return iBitsRead; } - static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, @@ -1430,66 +1403,6 @@ static int32_t ReadRMSEnvelope( } -#ifdef ENABLE_PMOD_ADJUST -static int32_t ReadPmodInformation( - int32_t **ppiHiSMRFlags, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iChannels, - int32_t iNumBands ) -{ - int32_t iBitsRead; - int32_t c; - iBitsRead = 0; - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - int32_t iFlags = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( iFlags ) - { - for ( b = 0; b < iNumBands; b++ ) - { - ppiHiSMRFlags[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - } - else - { - for ( b = 0; b < iNumBands; b++ ) - { - ppiHiSMRFlags[c][b] = 0; - } - } - } -#ifdef WRITE_HISMR_FLAGS - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "hismr_dec.txt", "wt" ); - } - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) - { - if ( c == iChannels - 1 && b == iNumBands - 1 ) - { - fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); - } - else - { - fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); - } - } - } - } -#endif - return iBitsRead; -} -#endif - - static int32_t ReadAllocInformation( int32_t *piAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ) diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c index 8052edee4a6d552467003afe502cb34a7eefa6f5..4ad176ec0dcd9a5e06527ae5deff400aa6ca6acf 100644 --- a/lib_rend/ivas_lcld_encoder.c +++ b/lib_rend/ivas_lcld_encoder.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -39,9 +39,6 @@ #include "ivas_lcld_rom_tables.h" #include "prot.h" #include "ivas_prot_rend.h" -#ifdef ENABLE_PMOD_ADJUST -#include "ton_corr.h" -#endif #include "wmc_auto.h" /*------------------------------------------------------------------------------------------* @@ -55,7 +52,6 @@ struct LCLD_ENCODER int32_t iNumBlocks; int32_t iTargetBitRate; - int32_t iTargetBitsPerFrame; int32_t iNumBands; const int32_t *piBandwidths; @@ -66,9 +62,6 @@ struct LCLD_ENCODER int32_t piLRPhaseDiffs[MAX_BANDS]; int32_t iAllowSidePred; -#ifdef ENABLE_PMOD_ADJUST - int32_t **ppiHiSMRFlags; -#endif RMSEnvelopeGrouping *psRMSEnvelopeGrouping; @@ -92,6 +85,56 @@ struct LCLD_ENCODER PredictionEncoder *psPredictionEncoder; }; +/*------------------------------------------------------------------------------------------* + * Function Quantize() + * + * + *------------------------------------------------------------------------------------------*/ + +static int32_t Quantize( + const float fVal, + const float fScale, + int32_t *iSign, + const int32_t iMaxVal ) +{ + int32_t iVal; + if ( fVal > 0.0f ) + { + iVal = (int32_t) ( fScale * fVal + 0.5f ); + *iSign = 0; + } + else + { + iVal = (int32_t) ( -fScale * fVal + 0.5f ); + *iSign = 1; + } + iVal = ( iVal < iMaxVal ) ? iVal : iMaxVal; + + return iVal; +} + +/*------------------------------------------------------------------------------------------* + * Function UnQuantize() + * + * + *------------------------------------------------------------------------------------------*/ + +static float UnQuantize( + const int32_t iVal, + const float fScale, + const int32_t iSign ) +{ + float fVal; + if ( iSign == 0 ) + { + fVal = fScale * (float) iVal; + } + else + { + fVal = -fScale * (float) iVal; + } + return fVal; +} /*------------------------------------------------------------------------------------------* * Function CreateLCLDEncoder() @@ -104,13 +147,18 @@ ivas_error CreateLCLDEncoder( const int32_t iSampleRate, const int32_t iChannels, const int32_t iTargetBitRate, - const int32_t iAllowSidePred ) + const int32_t iAllowSidePred, + const int16_t iNumBlocks, + const int16_t iNumSubSets ) { int32_t n; LCLDEncoder *psLCLDEncoder; ivas_error error; + int32_t iMaxNumPredBands = 0; assert( iSampleRate == 48000 ); // Fix + assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); + assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS ); if ( ( psLCLDEncoder = (LCLDEncoder *) malloc( sizeof( LCLDEncoder ) ) ) == NULL ) { @@ -119,14 +167,18 @@ ivas_error CreateLCLDEncoder( psLCLDEncoder->iSampleRate = iSampleRate; psLCLDEncoder->iChannels = iChannels; - psLCLDEncoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; + psLCLDEncoder->iNumBlocks = (int32_t) iNumBlocks; psLCLDEncoder->iAllocOffset = 0; psLCLDEncoder->iTargetBitRate = iTargetBitRate; - psLCLDEncoder->iTargetBitsPerFrame = iTargetBitRate * LCLD_BLOCKS_PER_FRAME * LCLD_BANDS / iSampleRate; - psLCLDEncoder->iNumBands = MAX_BANDS_48; // Fix - psLCLDEncoder->piBandwidths = c_aiBandwidths48; // Fix + psLCLDEncoder->piBandwidths = c_aiBandwidths48; + psLCLDEncoder->iNumBands = DEF_BANDS_48; /* 22 bands = 50 CLDFB bands (rather than 23 bands) */ + for ( n = 0; n < psLCLDEncoder->iNumBands; n++ ) + { + iMaxNumPredBands += psLCLDEncoder->piBandwidths[n]; + } + psLCLDEncoder->iMSMode = 0; if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) @@ -194,23 +246,11 @@ ivas_error CreateLCLDEncoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } -#ifdef ENABLE_PMOD_ADJUST - if ( ( psLCLDEncoder->ppiHiSMRFlags = (int32_t **) malloc( psLCLDEncoder->iChannels * sizeof( int32_t * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#endif for ( n = 0; n < iChannels; n++ ) { int32_t k; -#ifdef ENABLE_PMOD_ADJUST - if ( ( psLCLDEncoder->ppiHiSMRFlags[n] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#endif if ( ( psLCLDEncoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -302,7 +342,7 @@ ivas_error CreateLCLDEncoder( } } - if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks ) ) != IVAS_ERR_OK ) + if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks, (int32_t) iNumSubSets, iMaxNumPredBands ) ) != IVAS_ERR_OK ) { return error; } @@ -350,16 +390,6 @@ void DeleteLCLDEncoder( } free( psLCLDEncoder->ppiGroupLengths ); } -#ifdef ENABLE_PMOD_ADJUST - if ( psLCLDEncoder->ppiHiSMRFlags != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - free( psLCLDEncoder->ppiHiSMRFlags[n] ); - } - free( psLCLDEncoder->ppiHiSMRFlags ); - } -#endif if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) { for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) @@ -483,10 +513,6 @@ static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLe static int32_t WriteHeaderInformation( const int32_t iNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); -#ifdef ENABLE_PMOD_ADJUST -static int32_t WritePmodInformation( const int32_t **ppiHiSMRFlags, IVAS_SPLIT_REND_BITS_HANDLE pBits, int32_t iChannels, int32_t iNumBands ); -#endif - static int32_t WriteMSInformation( const int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiffs, const int32_t *piMSPredCoefs, int32_t iNumMSPredBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits ); @@ -497,8 +523,7 @@ static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REN static int32_t WriteLCLDData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, IVAS_SPLIT_REND_BITS_HANDLE pBits ); -static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t **ppiPredEnable, float **ppfA1Real, float **ppfA1Imag ); - +static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); /*------------------------------------------------------------------------------------------* * Function EncodeLCLDFrame() @@ -519,6 +544,7 @@ int32_t EncodeLCLDFrame( int32_t iNumMSBands = 0; iAvailableBits = available_bits; // HCBR for now iBitsWritten = 0; + assert( available_bits <= pBits->buf_len * 8 ); /* Do MS calc here */ if ( psLCLDEncoder->iChannels == 2 ) @@ -540,9 +566,6 @@ int32_t EncodeLCLDFrame( } } -#ifdef ENABLE_PMOD_ADJUST - CalcTonQuotas( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, pppfLCLDReal, pppfLCLDImag, psLCLDEncoder->ppiHiSMRFlags ); -#endif /* Compute Grouping and RMS Envelopes */ if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) @@ -612,12 +635,6 @@ int32_t EncodeLCLDFrame( iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); -#ifdef ENABLE_PMOD_ADJUST - iBitsWritten += WritePmodInformation( psLCLDEncoder->ppiHiSMRFlags, - pBits, - psLCLDEncoder->iChannels, - psLCLDEncoder->iNumBands ); -#endif if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) { @@ -648,7 +665,20 @@ int32_t EncodeLCLDFrame( } } } - +#ifdef DEBUG_WRITE_PREDICTORS + { + static FILE *fid; + if ( !fid ) + fid = fopen( "pred_enc.txt", "wt" ); + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + int16_t b; + for ( b = 0; b < 60; b++ ) + fprintf( fid, "%.5f ", (float) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n][b] * psLCLDEncoder->psPredictionEncoder->ppfA1Imag[n][b] ); + } + fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] ); + } +#endif iAvailableBits -= iBitsWritten; ComputeAllocation( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, @@ -665,9 +695,7 @@ int32_t EncodeLCLDFrame( psLCLDEncoder->pppiQLCLDImag, psLCLDEncoder->pppiLCLDSignReal, psLCLDEncoder->pppiLCLDSignImag, - psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, - psLCLDEncoder->psPredictionEncoder->ppfA1Real, - psLCLDEncoder->psPredictionEncoder->ppfA1Imag ); + psLCLDEncoder->psPredictionEncoder ); iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, pBits ); @@ -710,6 +738,21 @@ int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder ) * *------------------------------------------------------------------------------------------*/ +enum MSPred_Types +{ + MS_PHASE_AND_PRED = 0, /* LR phase alignment + real-valued M/S prediction */ + MS_PRED_ONLY = 1, /* real-valued M/S prediction */ + MS_PHASE_ONLY = 2 /* LR phase alignment + M/S */ +}; + +enum MS_BS_TYPES +{ + MS_OFF = 0, + MS_ALL = 1, + MS_SOME = 2, + MS_PRED = 3 +}; + static int32_t MSModeCalculation( const int32_t iNumBlocks, const int32_t iNumBands, @@ -725,20 +768,45 @@ static int32_t MSModeCalculation( int32_t b; int32_t iFBOffset; int32_t iNumMSBands; - int32_t piMSPredFlags[MAX_BANDS]; - int32_t iNumMSPredBands = 0; - float msBitsReduction = 0.0f; - float msPredBitsReduction = 0.0f; - int32_t msBits; - int32_t msPredBits; + int32_t iMSPredType; + float fMSBitGain = 0.0f; + float pfMSPredBitGain[3] = { 0.0f }; float fPred; -#if defined SIMPLE_PHASE - void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_p_pi_2, &rot_pm_pi, &rot_m_pi_2 }; -#endif - const float one_by_log10_2 = 3.32192809488736f; + int32_t piMSPredFlags0[MAX_BANDS] = { 0 }; + int32_t piMSPredFlags1[MAX_BANDS] = { 0 }; + int32_t piMSPredFlags2[MAX_BANDS] = { 0 }; + int32_t *ppiMSPredFlags[3]; + int32_t piMSPredCoefs0[MAX_BANDS] = { 0 }; + int32_t piMSPredCoefs1[MAX_BANDS] = { 0 }; + int32_t piMSPredCoefs2[MAX_BANDS] = { 0 }; + int32_t *ppiMSPredCoefs[3]; + int32_t piMSPredPhase0[MAX_BANDS] = { 0 }; + int32_t piMSPredPhase1[MAX_BANDS] = { 0 }; + int32_t piMSPredPhase2[MAX_BANDS] = { 0 }; + int32_t *ppiMSPredPhase[3]; + int32_t iMsInfoBits; + int32_t piMsPredInfoBits[3] = { 0 }; + + const float feps = 1e-12f; + float fBitsFactor = 3.32192809488736f; /* = 1/log10(2), from dB/10 to bits assuming 1 bit per log2(SNR) or 1 bit per 3dB SNR */ + if ( iNumBlocks < LCLD_BLOCKS_PER_FRAME ) + { + fBitsFactor *= ( 0.7f + (float) ( iNumBlocks - 4 ) / (float) ( LCLD_BLOCKS_PER_FRAME - 4 ) * ( 1.0f - 0.7f ) ); /* Tuning for relatively higher side rate due to shorter frame length */ + } - set_l( piMSPredFlags, 0, MAX_BANDS ); - *piMSMode = 0; + ppiMSPredFlags[0] = piMSPredFlags0; + ppiMSPredFlags[1] = piMSPredFlags1; + ppiMSPredFlags[2] = piMSPredFlags2; + + ppiMSPredCoefs[0] = piMSPredCoefs0; + ppiMSPredCoefs[1] = piMSPredCoefs1; + ppiMSPredCoefs[2] = piMSPredCoefs2; + + ppiMSPredPhase[0] = piMSPredPhase0; + ppiMSPredPhase[1] = piMSPredPhase1; + ppiMSPredPhase[2] = piMSPredPhase2; + + *piMSMode = MS_OFF; iFBOffset = 0; iNumMSBands = 0; for ( b = 0; b < iNumBands; b++ ) @@ -750,7 +818,7 @@ static int32_t MSModeCalculation( float fSideEnergy; float fLRRatio; float fMSRatio; - float fMSPredRatio; + float pfMSPredRatio[3] = { 0.0f }; float fMidEnergyPred; float fSideEnergyPred; float fLRCovReal = 0.0f; @@ -758,11 +826,12 @@ static int32_t MSModeCalculation( int32_t iPhase; int32_t iPred; int32_t tabIdx = 0; - + float fNumLines = (float) ( iNumBlocks * piBandwidths[b] * 2 ); /* per band per channel */ + float fLevelToSMRdBFactor = (float) c_aiDefaultTheta48[b] / (float) ( 1 << PERCEPTUAL_MODEL_SLGAIN_SHIFT ); /* frequency dependent SMR slope in psy model */ fLeftEnergy = 0.0f; fRightEnergy = 0.0f; - fMidEnergy = 0.0; - fSideEnergy = 0.0; + fMidEnergy = 0.0f; + fSideEnergy = 0.0f; for ( n = 0; n < piBandwidths[b]; n++ ) { @@ -791,140 +860,147 @@ static int32_t MSModeCalculation( iFBOffset++; } - /* compute L/R phase difference if high coherence */ + /* M/S prediction without phase alignment*/ + fPred = 0.25f * ( fLeftEnergy - fRightEnergy ) / ( fMidEnergy + feps ); + iPred = quantPred( fPred ); + fPred = dequantPred( iPred ); + fSideEnergyPred = fSideEnergy + ( fPred * fPred * fMidEnergy - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + + ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred; + ppiMSPredPhase[MS_PRED_ONLY][b] = 0; + pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) ); + + /* Phase alignment*/ + iPhase = 0; if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) { - float fPhase = (float) atan2( fLRCovImag, fLRCovReal ); // ToDo: replace by atan2f() + float fPhase = atan2f( fLRCovImag, fLRCovReal ); iPhase = quantPhase( fPhase ); } - else - { - iPhase = 0; - } - piLRPhaseDiffs[b] = iPhase; - /* adjust covariance based on phase rotation */ -#ifdef SIMPLE_PHASE - cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImagSimple[iPhase][0], -c_afRotRealImagSimple[iPhase][1] ); -#else + /* adjust covariance */ tabIdx = iPhase - PHASE_MIN_VAL; cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); -#endif - /* compute MS prediction coefficient based on LR covariance*/ + + /* compute MS prediction coefficient based on adjusted covariance */ fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); - /* M/S prediction */ + /* M/S with LR phase alignment but without prediction */ + ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0; + ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase; + pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + + /* M/S with LR phase alignment and prediction */ fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; iPred = quantPred( fPred ); fPred = dequantPred( iPred ); - piMSPredCoefs[b] = iPred; - - /* evaluation */ fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ - fMSPredRatio = log10f( ( fMidEnergyPred + 1e-12f ) / ( fSideEnergyPred + 1e-12f ) ); - - fLeftEnergy = log10f( fLeftEnergy + 1e-12f ); - fRightEnergy = log10f( fRightEnergy + 1e-12f ); - fMidEnergy = log10f( fMidEnergy + 1e-12f ); - fSideEnergy = log10f( fSideEnergy + 1e-12f ); + ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred; + ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase; + pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); - if ( fLeftEnergy > fRightEnergy ) - { - fLRRatio = fLeftEnergy - fRightEnergy; - } - else - { - fLRRatio = fRightEnergy - fLeftEnergy; - } + /* Plain M/S */ + fLeftEnergy = log10f( fLeftEnergy + feps ); + fRightEnergy = log10f( fRightEnergy + feps ); + fMidEnergy = log10f( fMidEnergy + feps ); + fSideEnergy = log10f( fSideEnergy + feps ); - if ( fMidEnergy > fSideEnergy ) - { - fMSRatio = fMidEnergy - fSideEnergy; - } - else - { - fMSRatio = fSideEnergy - fMidEnergy; - } + fLRRatio = ( fLeftEnergy > fRightEnergy ? fLeftEnergy - fRightEnergy : fRightEnergy - fLeftEnergy ); + fMSRatio = ( fMidEnergy > fSideEnergy ? fMidEnergy - fSideEnergy : fSideEnergy - fMidEnergy ); if ( fMSRatio > fLRRatio ) { iNumMSBands++; piMSFlags[b] = 1; + fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; } else { piMSFlags[b] = 0; } + piLRPhaseDiffs[b] = 0; + piMSPredCoefs[b] = 0; - if ( fMSRatio > fLRRatio ) - { - float maskThresShift_dB_by_10 = ( fMSRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; - msBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; /* * 2 for real/imag */ - } - - if ( fMSPredRatio > fLRRatio ) - { - float maskThresShift_dB_by_10 = ( fMSPredRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; - msPredBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; - iNumMSPredBands++; - piMSPredFlags[b] = 1; - } - else + /* MSPred bit gains based on increase of level ratio compared to L/R ratio and the level dependent psy-model */ + for ( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) { - piMSPredFlags[b] = 0; + if ( pfMSPredRatio[iMSPredType] > fLRRatio ) + { + ppiMSPredFlags[iMSPredType][b] = 1; + pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + } } } - msPredBits = CountMSBits( iNumBands, 3, piMSPredFlags, piLRPhaseDiffs, piMSPredCoefs ); - msPredBitsReduction = max( msPredBitsReduction - (float) msPredBits, 0.0f ); - msBits = CountMSBits( iNumBands, 2, piMSFlags, NULL, NULL ); - msBitsReduction = max( msBitsReduction - (float) msBits, 0.0f ); -#ifdef DEBUG_WRITE_MS_PRED + /* remove signalling cost from bit gains */ + for ( iMSPredType = 0; iMSPredType < 3; iMSPredType++ ) { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "bit_red.txt", "wt" ); - } - fprintf( fid, "%.1f %.1f %d %d\n", msBitsReduction, msPredBitsReduction, msBits, msPredBits ); + piMsPredInfoBits[iMSPredType] = CountMSBits( iNumBands, MS_PRED, ppiMSPredFlags[iMSPredType], ppiMSPredPhase[iMSPredType], ppiMSPredCoefs[iMSPredType] ); + pfMSPredBitGain[iMSPredType] = max( pfMSPredBitGain[iMSPredType] - piMsPredInfoBits[iMSPredType], 0.0f ); } -#endif - if ( iAllowSidePred && msPredBitsReduction > 1.1f * msBitsReduction ) + /* find the best M/S Pred type */ + iMSPredType = MS_PHASE_AND_PRED; + iMSPredType = ( pfMSPredBitGain[MS_PRED_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PRED_ONLY : iMSPredType ); + iMSPredType = ( pfMSPredBitGain[MS_PHASE_ONLY] > pfMSPredBitGain[iMSPredType] ? MS_PHASE_ONLY : iMSPredType ); + + /* plain M/S */ + iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL ); + fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f ); + if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain ) { - *piMSMode = 3; + *piMSMode = MS_PRED; + iNumMSBands = 0; for ( b = 0; b < iNumBands; b++ ) { - piMSFlags[b] = piMSPredFlags[b]; + piMSFlags[b] = ppiMSPredFlags[iMSPredType][b]; + if ( piMSFlags[b] == 1 ) + { + piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b]; + piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b]; + iNumMSBands++; + } + else + { + piMSPredCoefs[b] = 0; + piLRPhaseDiffs[b] = 0; + } } - iNumMSBands = iNumMSPredBands; } else if ( iNumMSBands == iNumBands ) { - *piMSMode = 1; + *piMSMode = MS_ALL; } else if ( iNumMSBands > 0 ) { - *piMSMode = 2; + *piMSMode = MS_SOME; } else { - *piMSMode = 0; + *piMSMode = MS_OFF; } - - if ( *piMSMode > 0 ) +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + int32_t iActualInfoBits = CountMSBits( iNumBands, *piMSMode, piMSFlags, piLRPhaseDiffs, piMSPredCoefs ); + if ( !fid ) + fid = fopen( "ms_info_bits.txt", "wt" ); + fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits ); + } +#endif + if ( *piMSMode != MS_OFF ) { iFBOffset = 0; for ( b = 0; b < iNumBands; b++ ) { -#if defined SIMPLE_PHASE - void ( *pFuncPhaseRotate )( float *, float * ) = pFuncPhaseRotateOptions[piLRPhaseDiffs[b]]; -#endif if ( piMSFlags[b] == 1 ) { int32_t n; + int32_t phaseIdx; + phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; + fPred = dequantPred( piMSPredCoefs[b] ); for ( n = 0; n < piBandwidths[b]; n++ ) { int32_t k; @@ -935,16 +1011,9 @@ static int32_t MSModeCalculation( float fSideReal; float fSideImag; - if ( *piMSMode == 3 ) + if ( *piMSMode == MS_PRED ) { -#ifdef SIMPLE_PHASE - ( *pFuncPhaseRotate )( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset] ); -#else - int32_t phaseIdx; - - phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); -#endif } fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); @@ -952,9 +1021,8 @@ static int32_t MSModeCalculation( fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); - if ( *piMSMode == 3 ) + if ( *piMSMode == MS_PRED ) { - fPred = dequantPred( piMSPredCoefs[b] ); fSideReal -= fPred * fMidReal; fSideImag -= fPred * fMidImag; } @@ -973,47 +1041,30 @@ static int32_t MSModeCalculation( } } } - #ifdef DEBUG_WRITE_MS_PRED { - static FILE *fid = 0; + static FILE *fid; if ( !fid ) - { - fid = fopen( "ms_mode_enc_raw.txt", "wt" ); - } - writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumBands, iNumBands, fid, piMSFlags ); + fid = fopen( "ms_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); } #endif - if ( *piMSMode == 3 ) + if ( *piMSMode == MS_PRED ) { /* Differential Coding of Phase Data*/ PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); #ifdef DEBUG_WRITE_MS_PRED { - static FILE *fid = 0; + static FILE *fid; if ( !fid ) - { - fid = fopen( "ms_mode_enc.txt", "wt" ); - } + fid = fopen( "ms_pred_enc.txt", "wt" ); writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); } #endif /* Differential Coding*/ -#ifndef SIMPLE_PHASE EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); -#endif EncodePredCoef( piMSPredCoefs, iNumMSBands ); -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "ms_mode_enc_diff.txt", "wt" ); - } - writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); - } -#endif } return iNumMSBands; @@ -1057,7 +1108,6 @@ static void RemoveRMSEnvelope( return; } - static void QuantizeSpectrumDPCM_Opt( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1070,137 +1120,106 @@ static void QuantizeSpectrumDPCM_Opt( int32_t **ppiQImag, int32_t **ppiSignReal, int32_t **ppiSignImag, + int32_t iNumSubSets, + int32_t iSubSetId, int32_t *piPredEnable, float *pfA1Real, - float *pfA1Imag ) /* Pass in 2 previous value buffers NULLABLE */ + float *pfA1Imag, + float *pfPredStateReal, + float *pfPredStateImag ) { - int32_t b, m, n, iBlockOffset; - float fVal, fPrevReal, fPrevImag, fPredReal, fPredImag; + int32_t b, n; int32_t iFBOffset; - int32_t k, iAlloc, iQuantValue, iMaxQuantVal; + int32_t k, iAlloc, iMaxQuantVal; float fSCFGain, fInvSCFGain; iFBOffset = 0; for ( b = 0; b < iNumBands; b++ ) { + int32_t m; for ( m = 0; m < piBandwidths[b]; m++ ) { - iBlockOffset = 0; - fPrevReal = 0.0; - fPrevImag = 0.0; - for ( n = 0; n < iNumGroups; n++ ) + int32_t iBlockOffset = 0; + if ( piPredEnable[iFBOffset] == 1 ) { - iAlloc = ppiAlloc[n][b]; - iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; - fSCFGain = c_afScaleFactor[iAlloc]; - fInvSCFGain = c_afInvScaleFactor[iAlloc]; - - if ( piPredEnable[iFBOffset] == 1 ) + float fReal; + float fImag; + int32_t iSubset = iFBOffset % iNumSubSets; + float fPrevReal = 0.0f; + float fPrevImag = 0.0f; + if ( iSubset != iSubSetId ) + { + /* run predictors across sub-frames */ + fPrevReal = pfPredStateReal[iFBOffset]; + fPrevImag = pfPredStateImag[iFBOffset]; + } + for ( n = 0; n < iNumGroups; n++ ) { + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; for ( k = 0; k < piGroupLengths[n]; k++ ) { - fPredReal = 0.0; - fPredImag = 0.0; - - fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; - fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; - - fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 1; - } - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - - ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; - - fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 1; - } - - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; - - - if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) - { - fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; - } - else - { - fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; - } - if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) - { - fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; - } - else - { - fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; - } + /* prediction */ + fReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; + fImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; + + ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset] + fReal, /* quantize residual */ + fSCFGain, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset] + fImag, + fSCFGain, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + fPrevReal = UnQuantize( ppiQReal[iBlockOffset][iFBOffset], + fInvSCFGain, + ppiSignReal[iBlockOffset][iFBOffset] ) - + fReal; /* add prediction to quantized residual = reconstructed sample */ + + fPrevImag = UnQuantize( ppiQImag[iBlockOffset][iFBOffset], + fInvSCFGain, + ppiSignImag[iBlockOffset][iFBOffset] ) - + fImag; iBlockOffset++; - } - } - else + } /* group length */ + } /* groups */ + pfPredStateReal[iFBOffset] = fPrevReal; + pfPredStateImag[iFBOffset] = fPrevImag; + } /* predEnable */ + else + { /* no prediction */ + for ( n = 0; n < iNumGroups; n++ ) { + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; for ( k = 0; k < piGroupLengths[n]; k++ ) { - fVal = ppfReal[iBlockOffset][iFBOffset]; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 1; - } - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset], + fSCFGain, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal ); - ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset], + fSCFGain, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal ); - fVal = ppfImag[iBlockOffset][iFBOffset]; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 1; - } - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; iBlockOffset++; - } - } - } - + } /* group length */ + } /* groups */ + } /* predEnable */ iFBOffset++; - } - } - - return; + } /* bandwidth */ + } /* bands */ } - static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1362,13 +1381,6 @@ static int32_t WriteMSInformation( if ( anyNonZero ) { -#ifdef SIMPLE_PHASE - for ( b = 0; b < iNumMSPredBands; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[b], SIMPLE_PHASE_BITS ); - iBitsWritten += SIMPLE_PHASE_BITS; - } -#else ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); iBitsWritten += PHASE_BAND0_BITS; for ( b = 1; b < iNumMSPredBands; b++ ) @@ -1377,7 +1389,6 @@ static int32_t WriteMSInformation( ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; } -#endif } anyNonZero = 0; @@ -1540,70 +1551,6 @@ static int32_t WriteRMSEnvelope( } -#ifdef ENABLE_PMOD_ADJUST -static int32_t WritePmodInformation( - const int32_t **ppiHiSMRFlags, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iChannels, - int32_t iNumBands ) -{ - int32_t iBitsWritten, c, b; - - iBitsWritten = 0; - - for ( c = 0; c < iChannels; c++ ) - { - int32_t anyNonZero = 0; - const int32_t *flags = ppiHiSMRFlags[c]; - for ( b = 0; b < iNumBands; b++ ) - { - if ( flags[b] ) - { - anyNonZero = 1; - break; - } - } - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); - iBitsWritten += 1; - if ( anyNonZero ) - { - for ( b = 0; b < iNumBands; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, flags[b], 1 ); - iBitsWritten += 1; - } - } - } -#ifdef WRITE_HISMR_FLAGS - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "hismr_enc.txt", "wt" ); - } - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) - { - if ( c == iChannels - 1 && b == iNumBands - 1 ) - { - fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); - } - else - { - fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); - } - } - } - } -#endif - - return iBitsWritten; -} -#endif - - static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ) @@ -1764,9 +1711,7 @@ static int32_t ComputeAllocation( int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, - int32_t **ppiPredEnable, - float **ppfA1Real, - float **ppfA1Imag ) + PredictionEncoder *psPredictionEncoder ) { int32_t iBitsUsed, iDone, iDelta; int32_t b, k, n; @@ -1800,6 +1745,12 @@ static int32_t ComputeAllocation( } } + if ( psPredictionEncoder->iNumSubSets > 1 ) + { + mvr2r( psPredictionEncoder->ppfPredStateReal[n], psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); + mvr2r( psPredictionEncoder->ppfPredStateImag[n], psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); + } + QuantizeSpectrumDPCM_Opt( piNumGroups[n], (const int32_t *) ppiGroupLengths[n], iNumBands, @@ -1811,15 +1762,19 @@ static int32_t ComputeAllocation( pppiQImag[n], pppiSignReal[n], pppiSignImag[n], - ppiPredEnable[n], - ppfA1Real[n], - ppfA1Imag[n] ); + psPredictionEncoder->iNumSubSets, + psPredictionEncoder->iSubSetId, + psPredictionEncoder->ppiPredBandEnable[n], + psPredictionEncoder->ppfA1Real[n], + psPredictionEncoder->ppfA1Imag[n], + psPredictionEncoder->ppfPredStateRealTmp[n], + psPredictionEncoder->ppfPredStateImagTmp[n] ); iBitsUsed += CountLCLDBits( piNumGroups[n], (const int32_t *) ppiGroupLengths[n], iNumBands, piBandwidths, - (const int32_t *) ppiPredEnable[n], + (const int32_t *) psPredictionEncoder->ppiPredBandEnable[n], pppiAlloc[n], pppiQReal[n], pppiQImag[n] ); @@ -1866,6 +1821,19 @@ static int32_t ComputeAllocation( } } + if ( psPredictionEncoder->iNumSubSets > 1 ) + { + for ( n = 0; n < iChannels; n++ ) + { + mvr2r( psPredictionEncoder->ppfPredStateRealTmp[n], psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); + mvr2r( psPredictionEncoder->ppfPredStateImagTmp[n], psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); + } + if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) + { + psPredictionEncoder->iSubSetId = 0; + } + } + // printf("%d\n",*piAllocOffset); // printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); diff --git a/lib_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h index 2af8355c9772f5b4e1d55d0b8bb1bc7b6f0d1446..6fbc250fcc73c9119b951be53c681c855c8ec5ca 100644 --- a/lib_rend/ivas_lcld_prot.h +++ b/lib_rend/ivas_lcld_prot.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -43,11 +43,13 @@ typedef struct LCLD_ENCODER LCLDEncoder; ivas_error CreateLCLDEncoder( - LCLDEncoder **psLCLDEncoder, + LCLDEncoder **psLCLDEncoder_out, const int32_t iSampleRate, const int32_t iChannels, const int32_t iTargetBitRate, - const int32_t iAllowSidePred ); + const int32_t iAllowSidePred, + const int16_t iNumBlocks, + const int16_t iNumSubSets ); void DeleteLCLDEncoder( LCLDEncoder *psLCLDEncoder @@ -71,7 +73,8 @@ typedef struct LCLD_DECODER LCLDDecoder; ivas_error CreateLCLDDecoder( LCLDDecoder **psLCLDDecoder_out, const int32_t iSampleRate, - const int32_t iChannels ); + const int32_t iChannels, + const int32_t iNumBlocks ); void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder @@ -100,25 +103,6 @@ void cplxmult( float i2 ); -#ifdef SIMPLE_PHASE -void rot_pm_pi( - float *pr, - float *pi ); - -void rot_p_pi_2( - float *pr, - float *pi -); - -void rot_m_pi_2( - float *pr, - float *pi ); - -void rot_zero( - float *pr, - float *pi -); -#endif int32_t requantPhase( int32_t phaseQ @@ -195,7 +179,6 @@ typedef struct NOISE_GEN float *pfNoiseBuffer; } NoiseGen; - void DeleteNoiseGen( NoiseGen *psNoiseGen ); @@ -244,15 +227,24 @@ typedef struct PREDICTION_ENCODER int32_t iChannels; int32_t iNumBlocks; + int32_t iSubSetId; + int32_t iNumSubSets; + int32_t iMaxNumPredBands; + float ***pppfInpBufReal; /* channels, LCLD_PRED_WIN_LEN, bands */ + float ***pppfInpBufImag; + float **ppfPredStateReal; /* channels, bands */ + float **ppfPredStateImag; + float **ppfPredStateRealTmp; + float **ppfPredStateImagTmp; + float **ppfInpPrevReal; /* channels, bands */ + float **ppfInpPrevImag; + float *pfWindow; float pfRxxReal[2]; float pfRxxImag[2]; int32_t *piPredChanEnable; int32_t *piNumPredBands; - - float **ppfEstPredGain; - float **ppfEstPredBitGain; int32_t **ppiPredBandEnable; float **ppfA1Real; @@ -265,14 +257,16 @@ typedef struct PREDICTION_ENCODER ivas_error CreatePredictionEncoder( PredictionEncoder **psPredictionEncoder_out, const int32_t iChannels, - const int32_t iNumBlocks + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands ); void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ); -int32_t ComputePredictors( +void ComputePredictors( PredictionEncoder *psPredictionEncoder, float ***pppfReal, float ***pppfImag @@ -293,11 +287,12 @@ typedef struct PREDICTION_DECODER { int32_t iChannels; int32_t iNumBlocks; + int32_t iSubSetId; + int32_t iNumSubSets; + float **ppfPredStateReal; + float **ppfPredStateImag; int32_t *piPredChanEnable; - int32_t *piNumPredBands; - - float **ppfEstPredGain; int32_t **ppiPredBandEnable; float **ppfA1Real; @@ -327,7 +322,7 @@ int32_t ReadPredictors( IVAS_SPLIT_REND_BITS_HANDLE pBits ); -void ApplyInversePredictros( +void ApplyInversePredictors( PredictionDecoder *psPredictionDecoder, float ***pppfReal, float ***pppfImag diff --git a/lib_rend/ivas_lcld_rom_tables.c b/lib_rend/ivas_lcld_rom_tables.c index 144c44718ded3af0b950e61ad7ddedb0d301fe2a..c562624ffaba94d69280d904512851bd2b45d386 100644 --- a/lib_rend/ivas_lcld_rom_tables.c +++ b/lib_rend/ivas_lcld_rom_tables.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -39,12 +39,6 @@ /* clang-format off */ -const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2] = { - { 1.0f, 0.0f }, /* zero */ - { 0.0f, 1.0f }, /* pi/2 */ - { -1.0f, 0.0f }, /* pi */ - { 0.0f, -1.0f }, /* 3*pi/2 */ -}; /* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */ const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = diff --git a/lib_rend/ivas_lcld_rom_tables.h b/lib_rend/ivas_lcld_rom_tables.h index 132f52addf5f7d4a37a9fb481501b12b02b59024..8deb0aadf5e69fe570cc79af71396e3a7404b129 100644 --- a/lib_rend/ivas_lcld_rom_tables.h +++ b/lib_rend/ivas_lcld_rom_tables.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -45,9 +45,12 @@ #define LCLD_BLOCKS_PER_FRAME ( 16 ) #define LCLD_MAX_BLOCKS_PER_FRAME ( 16 ) #define LCLD_BANDS ( 60 ) +#define LCLD_PRED_WIN_LEN ( 16 ) +#define LCLD_MAX_NUM_PRED_SUBSETS ( 8 ) #define MAX_BANDS ( 23 ) #define MAX_BANDS_48 ( 23 ) +#define DEF_BANDS_48 ( 22 ) #define ENV_MIN ( -64 ) #define ENV_MAX ( 64 ) @@ -88,14 +91,6 @@ #define PHASE_DIFF_DIM ( 2 ) #define PHASE_BAND0_BITS ( 5 ) -#define SIMPLE_PHASE_MAX_VAL ( 3 ) -#define SIMPLE_PHASE_MIN_VAL ( 0 ) -#define SIMPLE_PHASE_BITS ( 2 ) -#define SIMPLE_PHASE_QUANT_FACTOR ( 2.0f / _PI_ ) - -#define TON_QUOTA_ABS_THRESHOLD ( 8.0f ) -#define TON_QUOTA_INC_THRESHOLD ( 4.0f ) - #define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) //#define USE_DEMOD_TABLES @@ -103,7 +98,6 @@ #define HUFF_DEC_TABLE_SIZE ( 16 ) extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; -extern const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2]; extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; extern const float c_afScaleFactor[ALLOC_TABLE_SIZE]; diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 0953e8a825dc3aecfe8a51b004da4a2400884199..da214e568a6c32d02ef624aa517e1bc97c0b9df7 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge.c index 3073ecec618e87e86129f136b187855286eca764..ac6d7b9652161d979e2dcf390d80a04f2105024f 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index 7ed4aeb0df58e8bae9796b8def729febb8a93240..8ca05a11977f2cc1f6e07e145f7b674a33d3ff23 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 2ba42cac6d13c9f9590d9f0a71460df101c13463..35d5531633d4399761c890da105ee5bf7ecd16e4 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index ef7966f6bfc357c31e0a80b83c06d8df774f687a..eb8ac6a5c58e684792788b01646cc60aa4e29c00 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 7fb2a06ad32536b6b53e7597e4fd9f5d850f2429..ca828de2e70dbd8d30cb2dba64a35287533aac72 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -391,27 +391,6 @@ static ivas_error DefaultBSplineModel( model = &( HrFiltSet_p->ModelParams ); modelITD = &( HrFiltSet_p->ModelParamsITD ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -#else - switch ( output_Fs ) - { - case 48000: - HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_48kHz; - HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_48kHz; - HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_48kHz; - break; - case 32000: - HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_32kHz; - HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_32kHz; - HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_32kHz; - break; - case 16000: - HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_16kHz; - HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_16kHz; - HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_16kHz; - break; - } -#endif /* Set ROM flag for correct deallocation */ model->modelROM = TRUE; diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index fd1c44060f7256bd13b7950578c2071be276ba54..f0c24ef8482a4a1f41bd7d66e9135ea504e24e85 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 2706a9c5c85604f398c3bcddb4341fb3e78a94db..3f580df504d6c32b4135aa7cc68bed5fa0bc55c0 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 061b790e1b46e9010d14a0b0162b528bbd3768fb..7ed69b5d9014feecc05cee6d1f98386f6d1279c2 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index 16f0e0b5d9961f2dc9048fd77ce8829f897c5f5e..98afd393b615ef30b819cf944931174932c944b3 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index 0f2c694875fe111effc2388ddb7d3768c0baa2dd..81cda7dd973d4fe4ea9c824fc50498fe7c32c01a 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 088c99bde24eaf4f8d357df1b3305e7e5889dc00..5d7d4d610f7a97c68060aa17139303aa8f0a0433 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -336,6 +336,11 @@ int16_t ivas_get_nchan_buffers_dec( nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); } + + if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->nchan_ism > 0 ) + { + nchan_out_buff = st_ivas->nchan_ism + CPE_CHANNELS; + } } else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { @@ -345,12 +350,10 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); } -#ifdef NONBE_FIX_979_OSBA_STEREO_5MS else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { nchan_out_buff = max( nchan_out_buff, 2 * BINAURAL_CHANNELS + 2 ); } -#endif else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 7dcea4363bf99123322a4f688fda0f4068ed2363..7de4ed3e8cdc05d65c964f100061f33b45b5cad5 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -245,7 +245,7 @@ void ivas_masa_ext_rend_parambin_render( ); ivas_error ivas_dirac_dec_init_binaural_data( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : HRTF structure for rendering */ + HRTFS_PARAMBIN_HANDLE *phHrtfParambin /* i : HRTF structure for rendering */ ); void ivas_dirac_dec_close_binaural_data( @@ -466,8 +466,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *diffuseness, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t sh_rot_max_order, - const float *p_Rmat, /* i : rotation matrix */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ const int16_t nchan_transport, /* i : number of transport channels */ @@ -534,8 +532,6 @@ void ivas_dirac_dec_compute_directional_responses( const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, - const int16_t shd_rot_max_order, /* i : split-order rotation method */ - const float *p_Rmat, /* i : rotation matrix */ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ); @@ -616,7 +612,6 @@ void ivas_HRTF_CRend_binary_close( HRTFS_CREND **hSetOfHRTF /* i/o: Set of HRTF handle */ ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_error ivas_HRTF_statistics_init( HRTFS_STATISTICS_HANDLE *hHrtfStatistics, /* i/o: HRTF statistics structure */ int32_t sampleRate /* i : Sample rate */ @@ -630,7 +625,6 @@ ivas_error ivas_HRTF_statistics_binary_open( HRTFS_STATISTICS **hHrtfStatistics /* i/o: HRTF statistics structure */ ); -#endif /*----------------------------------------------------------------------------------* * TD object renderer @@ -903,9 +897,7 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES HRTFS_STATISTICS_HANDLE hHrtfStatistics, -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT const int32_t output_Fs, const int16_t num_poses @@ -960,43 +952,17 @@ ivas_error ivas_rend_crendProcessSubframe( * Reverberator *----------------------------------------------------------------------------------*/ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_error ivas_binaural_reverb_init( -#else -ivas_error ivas_binaural_reverb_open_fastconv( -#endif REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ -#else -#endif const int16_t numBins, /* i : number of CLDFB bins */ const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ -#else - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const AUDIO_CONFIG internal_config, /* i : internal audio config for FastConv */ -#endif const int32_t sampling_rate, /* i : sampling rate */ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const float *defaultTimes, /* i : default reverberation times */ const float *defaultEne /* i : default reverberation energies */ -#else - const HRTFS_FASTCONV_HANDLE hHrtfFastConv /* i : FastConv HRTF handle */ -#endif ); -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -ivas_error ivas_binaural_reverb_open_parambin( - REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const int16_t numBins, /* i : number of CLDFB bins */ - const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate */ - const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ -); -#endif void ivas_binaural_reverb_close( REVERB_STRUCT_HANDLE *hReverb /* i/o: binaural reverb handle */ @@ -1014,13 +980,7 @@ void ivas_binaural_reverb_processSubframe( ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ -#else - const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ - const HRTFS_HANDLE hHrtf, /* i : HRTF handle */ - const float *lr_energy_and_iac[], /* i : precomuputed lr energies and iac */ -#endif RENDER_CONFIG_DATA *pConfig, /* i : Reverb configuration */ const int32_t output_Fs /* i : output sampling rate */ ); @@ -1177,23 +1137,12 @@ void ivas_reverb_calc_color_levels( float *pTarget_color_R ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_error ivas_reverb_prepare_cldfb_params( const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, const HRTFS_STATISTICS_HANDLE hHrtfStatistics, const int32_t output_Fs, float *pOutput_t60, float *pOutput_ene ); -#else -ivas_error ivas_reverb_prepare_cldfb_params( - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, - const HRTFS_FASTCONV_HANDLE hHrtfFastConv, - const AUDIO_CONFIG input_audio_config, - const int16_t use_brir, - const int32_t output_Fs, - float *pOutput_t60, - float *pOutput_ene ); -#endif void ivas_reverb_interpolate_acoustic_data( const int16_t input_table_size, @@ -1206,21 +1155,6 @@ void ivas_reverb_interpolate_acoustic_data( float *pOutput_dsr ); -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -void ivas_reverb_get_hrtf_set_properties( - float **ppHrtf_set_L_re, - float **ppHrtf_set_L_im, - float **ppHrtf_set_R_re, - float **ppHrtf_set_R_im, - const AUDIO_CONFIG input_audio_config, - const int16_t hrtf_count, - const int16_t in_freq_count, - const int16_t out_freq_count, - float *pOut_avg_pwr_L, - float *pOut_avg_pwr_R, - float *pOut_i_a_coherence -); -#endif /*---------------------------------------------------------------------------------* * Shoebox Prototypes @@ -1530,7 +1464,7 @@ ivas_error ivas_split_renderer_open( const int32_t output_Fs, const int16_t cldfb_in_flag, const int16_t pcm_out_flag, - const int16_t is_5ms_frame + const int16_t num_subframes ); void ivas_split_renderer_close( @@ -1541,7 +1475,9 @@ ivas_error ivas_splitBinLCLDEncOpen( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, const int32_t iSampleRate, const int16_t iChannels, - const int32_t iDataRate + const int32_t iDataRate, + const int16_t iNumBlocks, + const int16_t iNumIterations ); void ivas_splitBinLCLDEncClose( @@ -1559,7 +1495,9 @@ void ivas_splitBinLCLDEncProcess( ivas_error ivas_splitBinLCLDDecOpen( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, const int32_t iSampleRate, - const int16_t iChannels + const int16_t iChannels, + const int16_t iNumBlocks, + const int16_t iNumIterations ); void ivas_splitBinLCLDDecClose( @@ -1674,21 +1612,27 @@ void ivas_splitBinRendPLCsaveState( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ); void ivas_splitBinRendPLC_xf( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ); void ivas_splitBinRendPLC( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ); #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG @@ -1970,6 +1914,10 @@ int32_t ivas_split_rend_bitstream_read_int32( const int32_t bits ); +int32_t get_bit( + const int32_t state, + const int32_t bit_id +); void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend @@ -2022,10 +1970,11 @@ void ivas_split_rend_get_quant_params( ); ivas_error ivas_split_rend_choose_default_codec( - IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ - int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ - const int16_t cldfb_in_flag, /* i : flag indicating rendering in CLDFB */ - const int16_t pcm_out_flag /* i : flag to indicate PCM output */ + IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ + const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t num_subframes /* i : number of subframes */ ); #endif diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index 0b42a0b6ffa788b73668193ad3d978206a5f3856..9cab4198d50f354115b5fad6c6c72cebb112e127 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index c7a1abacf315af5feec12f634cf3ae62ea0c1e0f..93b175525ec8ddc39ae6c7883e69b08d3685fd1a 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index d85506bdbbad95c1f1842228a707cff63a97a556..1f791df39c484abd42569ba74715776fb8e7886d 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -939,69 +939,12 @@ static void set_fft_and_datablock_sizes( static void set_reverb_acoustic_data( ivas_reverb_params_t *pParams, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -#else - const AUDIO_CONFIG input_audio_config, - const HRTFS_HANDLE hHrtf, -#endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics, -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - const int16_t subframe_len, -#endif const int16_t nr_fc_input, const int16_t nr_fc_fft_filter ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES int16_t bin_idx; -#else - int16_t nr_out_ch, hrtf_idx, offset, iter_idx, bin_idx; -#endif float ln_1e6_inverted, delay_diff, exp_argument; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -#else - float *pHrtf_set_l_re[MAX_INTERN_CHANNELS]; - float *pHrtf_set_l_im[MAX_INTERN_CHANNELS]; - float *pHrtf_set_r_re[MAX_INTERN_CHANNELS]; - float *pHrtf_set_r_im[MAX_INTERN_CHANNELS]; - - /* use crend hrtf filters */ - if ( hHrtf != NULL ) - { - /* Compute HRTF set properties: average left/right energies, IA coherence */ - /* First, find the offset of the frequency-domain data for the 1st frame and assign HRTF pointers */ - for ( nr_out_ch = 0; nr_out_ch < BINAURAL_CHANNELS; nr_out_ch++ ) - { - for ( hrtf_idx = 0; hrtf_idx < hHrtf->max_num_ir; hrtf_idx++ ) - { - offset = 0; - for ( iter_idx = 0; iter_idx < hHrtf->num_iterations[hrtf_idx][nr_out_ch] - 1; iter_idx++ ) - { - offset += hHrtf->pIndex_frequency_max[hrtf_idx][nr_out_ch][iter_idx]; - } - - if ( nr_out_ch == 0 ) - { - pHrtf_set_l_re[hrtf_idx] = &hHrtf->pOut_to_bin_re[hrtf_idx][0][offset]; - pHrtf_set_l_im[hrtf_idx] = &hHrtf->pOut_to_bin_im[hrtf_idx][0][offset]; - } - else - { - pHrtf_set_r_re[hrtf_idx] = &hHrtf->pOut_to_bin_re[hrtf_idx][1][offset]; - pHrtf_set_r_im[hrtf_idx] = &hHrtf->pOut_to_bin_im[hrtf_idx][1][offset]; - } - } - } - - /* Compute HRTF set properties using frequency-domain HRTF data */ - ivas_reverb_get_hrtf_set_properties( pHrtf_set_l_re, pHrtf_set_l_im, pHrtf_set_r_re, pHrtf_set_r_im, input_audio_config, hHrtf->max_num_ir, subframe_len, - nr_fc_fft_filter, pParams->pHrtf_avg_pwr_response_l, pParams->pHrtf_avg_pwr_response_r, pParams->pHrtf_inter_aural_coherence ); - - pParams->pHrtf_avg_pwr_response_l_const = (const float *) pParams->pHrtf_avg_pwr_response_l; - pParams->pHrtf_avg_pwr_response_r_const = (const float *) pParams->pHrtf_avg_pwr_response_r; - pParams->pHrtf_inter_aural_coherence_const = (const float *) pParams->pHrtf_inter_aural_coherence; - } - -#endif /* interpolate input table data for T60 and DSR to the FFT filter grid */ ivas_reverb_interpolate_acoustic_data( nr_fc_input, pRoomAcoustics->pFc_input, pRoomAcoustics->pAcoustic_rt60, pRoomAcoustics->pAcoustic_dsr, nr_fc_fft_filter, pParams->pFc, pParams->pRt60, pParams->pDsr ); @@ -1095,16 +1038,10 @@ static ivas_error setup_FDN_branches( *------------------------------------------------------------------------*/ ivas_error ivas_reverb_open( - REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES + REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ -#else - const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ - const HRTFS_HANDLE hHrtf, /* i : HRTF handle */ - const float *lr_energy_and_iac[], /* i : precomuputed lr energies and iac */ -#endif - RENDER_CONFIG_HANDLE hRenderConfig, /* i : Renderer configuration handle */ - const int32_t output_Fs /* i : output sampling rate */ + RENDER_CONFIG_HANDLE hRenderConfig, /* i : Renderer configuration handle */ + const int32_t output_Fs /* i : output sampling rate */ ) { ivas_error error; @@ -1176,21 +1113,10 @@ ivas_error ivas_reverb_open( params.pFc[bin_idx] = freq_step * bin_idx; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES set_reverb_acoustic_data( ¶ms, &hRenderConfig->roomAcoustics, nr_fc_input, nr_fc_fft_filter ); params.pHrtf_avg_pwr_response_l_const = hHrtfStatistics->average_energy_l; params.pHrtf_avg_pwr_response_r_const = hHrtfStatistics->average_energy_r; params.pHrtf_inter_aural_coherence_const = hHrtfStatistics->inter_aural_coherence; -#else - if ( hHrtf == NULL && lr_energy_and_iac != NULL ) - { - params.pHrtf_avg_pwr_response_l_const = lr_energy_and_iac[0]; - params.pHrtf_avg_pwr_response_r_const = lr_energy_and_iac[1]; - params.pHrtf_inter_aural_coherence_const = lr_energy_and_iac[2]; - } - /* set up reverb acoustic data on the basis of HRTF data and renderer config */ - set_reverb_acoustic_data( ¶ms, input_audio_config, hHrtf, &hRenderConfig->roomAcoustics, subframe_len, nr_fc_input, nr_fc_fft_filter ); -#endif /* set reverb acoustic configuration based on renderer config */ #ifdef DEBUGGING @@ -1903,7 +1829,6 @@ static ivas_error ivas_binaural_reverb_open( return IVAS_ERR_OK; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES /*------------------------------------------------------------------------- * ivas_binaural_reverb_init() * @@ -1952,102 +1877,6 @@ ivas_error ivas_binaural_reverb_init( return error; } -#else -/*------------------------------------------------------------------------- - * ivas_binaural_reverb_open_fastconv() - * - * Allocate and initialize binaural room reverberator handle for FastConv - *------------------------------------------------------------------------*/ - -ivas_error ivas_binaural_reverb_open_fastconv( - REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const int16_t numBins, /* i : number of CLDFB bins */ - const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const AUDIO_CONFIG internal_config, /* i : internal audio config for FastConv */ - const int32_t sampling_rate, /* i : sampling rate */ - const HRTFS_FASTCONV_HANDLE hHrtfFastConv /* i : FastConv HRTF handle */ -) -{ - ivas_error error; - const float *revTimes; - const float *revEne; - float t60[CLDFB_NO_CHANNELS_MAX]; - float ene[CLDFB_NO_CHANNELS_MAX]; - int16_t preDelay; - - error = IVAS_ERR_OK; - - if ( ( roomAcoustics != NULL ) && roomAcoustics->override ) - { - revTimes = t60; - revEne = ene; - if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfFastConv, internal_config, false, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) - { - return error; - } - preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); - } - else - { - revTimes = hHrtfFastConv->fastconvReverberationTimes; - revEne = hHrtfFastConv->fastconvReverberationEneCorrections; - preDelay = 10; - } - - error = ivas_binaural_reverb_open( hReverbPr, numBins, numCldfbSlotsPerFrame, sampling_rate, revTimes, revEne, preDelay ); - - return error; -} - - -/*------------------------------------------------------------------------- - * ivas_binaural_reverb_open_parambin() - * - * Allocate and initialize binaural room reverberator handle for ParamBin - *------------------------------------------------------------------------*/ - -ivas_error ivas_binaural_reverb_open_parambin( - REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const int16_t numBins, /* i : number of CLDFB bins */ - const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate */ - const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ -) -{ - ivas_error error; - const float *revTimes; - const float *revEne; - float t60[CLDFB_NO_CHANNELS_MAX]; - float ene[CLDFB_NO_CHANNELS_MAX]; - int16_t preDelay; - - error = IVAS_ERR_OK; - - if ( ( roomAcoustics != NULL ) && roomAcoustics->override ) - { - revTimes = t60; - revEne = ene; - /* Todo Philips: This needs a suitable function for ParamBin here. */ - // if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfFastConv, internal_config, false, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) - // { - // return error; - // } - preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); - } - else - { - revTimes = hHrtfParambin->parametricReverberationTimes; - revEne = hHrtfParambin->parametricReverberationEneCorrections; - preDelay = 10; - } - - error = ivas_binaural_reverb_open( hReverbPr, numBins, numCldfbSlotsPerFrame, sampling_rate, revTimes, revEne, preDelay ); - - return error; -} -#endif /*------------------------------------------------------------------------- * ivas_binaural_reverb_close() diff --git a/lib_rend/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line.c index a91551f71d63d0edf763ba24077ad3e3a34126e9..ff6fb372a938717cac525c7bc0ba9054d594f6ed 100644 --- a/lib_rend/ivas_reverb_delay_line.c +++ b/lib_rend/ivas_reverb_delay_line.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_reverb_fft_filter.c b/lib_rend/ivas_reverb_fft_filter.c index 8b14d2d41ed9ef41881162e79a3e2e8fb5950845..7d4c1d87c84dc15ba04c9e659205891cb79fd7a5 100644 --- a/lib_rend/ivas_reverb_fft_filter.c +++ b/lib_rend/ivas_reverb_fft_filter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design.c index 20d9502c2ec24699b8276fd29dc8eb3cece083b4..65e6278cc4b2569ad800d1a585fe74d4bce5f954 100644 --- a/lib_rend/ivas_reverb_filter_design.c +++ b/lib_rend/ivas_reverb_filter_design.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -653,188 +653,3 @@ void ivas_reverb_interpolate_acoustic_data( return; } - -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -/*-------------------------------------------------------------------* - * ivas_reverb_get_hrtf_set_properties() - * - * Function analyses the HRTF set and computes avarage left/right power spectrum - * and frequency-dependent IA coherence. Expects frequency-domain HRTF input - *-------------------------------------------------------------------*/ - -void ivas_reverb_get_hrtf_set_properties( - float **ppHrtf_set_L_re, - float **ppHrtf_set_L_im, - float **ppHrtf_set_R_re, - float **ppHrtf_set_R_im, - const AUDIO_CONFIG input_audio_config, - const int16_t hrtf_count, - const int16_t in_freq_count, - const int16_t out_freq_count, - float *pOut_avg_pwr_L, - float *pOut_avg_pwr_R, - float *out_i_a_coherence ) -{ - const float foa_sum_coeffs[4][3] = { - { 1.0, 1.0f, 0.0f }, - { 1.0, -1.0f, 0.0f }, - { 1.0, 0.0f, 1.0f }, - { 1.0, 0.0f, -1.0f } - }; - const float inp_freq_step = 0.5f / (float) in_freq_count; - const float inp_freq_offset = 0.5f * inp_freq_step; - const float out_freq_step = 0.5f / (float) ( out_freq_count - 1 ); - - int16_t used_hrtf_count, base_idx, freq_idx, hrtf_idx, out_bin_idx, ch_index, is_ambisonics; - float hrtf_count_inverted, relative_pos, weight_1st; - float avg_pwr_left[2]; - float avg_pwr_right[2]; - float IA_coherence[2]; - - if ( input_audio_config == IVAS_AUDIO_CONFIG_FOA || input_audio_config == IVAS_AUDIO_CONFIG_HOA2 || input_audio_config == IVAS_AUDIO_CONFIG_HOA3 ) - { - is_ambisonics = 1; - used_hrtf_count = 4; /* Using only 1st order HRTFs */ - } - else - { - is_ambisonics = 0; - used_hrtf_count = hrtf_count; - } - - /* Interpolation (linear to a new grid) */ - base_idx = 0; - relative_pos = 0.0f; - hrtf_count_inverted = 1.0f / (float) used_hrtf_count; - - /* Loop over output frequency bins */ - for ( out_bin_idx = 0; out_bin_idx < out_freq_count; out_bin_idx++ ) - { - /* Computing normalized frequency for the current bin (1.0 corresponds to sampling rate) */ - const float norm_freq = out_freq_step * out_bin_idx; - - /* Computing the bin index in the source data */ - if ( in_freq_count == out_freq_count ) - { - base_idx = out_bin_idx; - } - else - { - const float tbl_index = ( norm_freq - inp_freq_offset ) / inp_freq_step; - - if ( tbl_index <= 0.0f ) /* In case of extrapolation (below 1st bin), choose nearest */ - { - base_idx = 0; - relative_pos = 0.0f; - } - else - { - base_idx = (int16_t) floorf( tbl_index ); - relative_pos = tbl_index - base_idx; - if ( base_idx > ( in_freq_count - 2 ) ) /* In case of extrapolation (above last bin), choose nearest */ - { - base_idx = in_freq_count - 2; - relative_pos = 1.0f; - } - } - } - - /* Computing 2 bins data for later interpolation */ - - /* Zeroing before accumalation for average value computing */ - avg_pwr_left[0] = 0.0f; - avg_pwr_left[1] = 0.0f; - avg_pwr_right[0] = 0.0f; - avg_pwr_right[1] = 0.0f; - IA_coherence[0] = 0.0f; - IA_coherence[1] = 0.0f; - - /* Get power spectra and cross - correlation between left and right hrtfs */ - /* Loop over all the HRTFs available */ - for ( hrtf_idx = 0; hrtf_idx < used_hrtf_count; hrtf_idx++ ) - { - /* Pointers to current HRTF data */ - float *current_base_L_ptr_re, *current_base_L_ptr_im, *current_base_R_ptr_re, *current_base_R_ptr_im; - - /* combined HRTF data used for FOA */ - float combined_channels_L_re[2]; - float combined_channels_L_im[2]; - float combined_channels_R_re[2]; - float combined_channels_R_im[2]; - - /* Process the frequency bins containing both real and img parts */ - /* In case of 5.1 or 7.1 formats, use the available HRTF paires directly*/ - if ( !is_ambisonics ) - { - current_base_L_ptr_re = ppHrtf_set_L_re[hrtf_idx] + base_idx; - current_base_R_ptr_re = ppHrtf_set_R_re[hrtf_idx] + base_idx; - current_base_L_ptr_im = ppHrtf_set_L_im[hrtf_idx] + base_idx; - current_base_R_ptr_im = ppHrtf_set_R_im[hrtf_idx] + base_idx; - } - - /* In case of FOA format, combine the W channel with the X/Y channels */ - else - { - for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) - { - combined_channels_L_re[freq_idx] = 0.0f; - combined_channels_R_re[freq_idx] = 0.0f; - combined_channels_L_im[freq_idx] = 0.0f; - combined_channels_R_im[freq_idx] = 0.0f; - - for ( ch_index = 0; ch_index < 3; ch_index++ ) - { - combined_channels_L_re[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_L_re[ch_index][base_idx + freq_idx]; - combined_channels_R_re[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_R_re[ch_index][base_idx + freq_idx]; - combined_channels_L_im[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_L_im[ch_index][base_idx + freq_idx]; - combined_channels_R_im[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_R_im[ch_index][base_idx + freq_idx]; - } - } - - current_base_L_ptr_re = &combined_channels_L_re[0]; - current_base_R_ptr_re = &combined_channels_R_re[0]; - current_base_L_ptr_im = &combined_channels_L_im[0]; - current_base_R_ptr_im = &combined_channels_R_im[0]; - } - - for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) - { - float L_re, L_im, R_re, R_im, C_re; - - L_re = current_base_L_ptr_re[freq_idx]; - R_re = current_base_R_ptr_re[freq_idx]; - L_im = current_base_L_ptr_im[freq_idx]; - R_im = current_base_R_ptr_im[freq_idx]; - - avg_pwr_left[freq_idx] += L_re * L_re + L_im * L_im; - avg_pwr_right[freq_idx] += R_re * R_re + R_im * R_im; - - /* Cross product (Re part) */ - C_re = L_re * R_re + L_im * R_im; - IA_coherence[freq_idx] += C_re; - } - } - - /* Compute the averages and the IA coherence */ - for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) - { - avg_pwr_left[freq_idx] *= hrtf_count_inverted; - avg_pwr_right[freq_idx] *= hrtf_count_inverted; - IA_coherence[freq_idx] = hrtf_count_inverted * IA_coherence[freq_idx] / - sqrtf( avg_pwr_left[freq_idx] * avg_pwr_right[freq_idx] ); - - /* Limiting to (0...1) range in case of small numerical errors or negative values */ - IA_coherence[freq_idx] = min( IA_coherence[freq_idx], 1.0f ); - IA_coherence[freq_idx] = max( IA_coherence[freq_idx], 0.0f ); - } - - /* Computing weighted average of 2 nearest values (1 below + 1 above) for linear interpolation */ - weight_1st = 1.0f - relative_pos; - pOut_avg_pwr_L[out_bin_idx] = weight_1st * avg_pwr_left[0] + relative_pos * avg_pwr_left[1]; - pOut_avg_pwr_R[out_bin_idx] = weight_1st * avg_pwr_right[0] + relative_pos * avg_pwr_right[1]; - out_i_a_coherence[out_bin_idx] = weight_1st * IA_coherence[0] + relative_pos * IA_coherence[1]; - } - - return; -} -#endif diff --git a/lib_rend/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter.c index ce73c9d864ed12705a82e739e891aef31c558b30..0d36f7968fb10be7328d165e44d30a1c8ab9219a 100644 --- a/lib_rend/ivas_reverb_iir_filter.c +++ b/lib_rend/ivas_reverb_iir_filter.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils.c index f62bf4eab4d6943f3f50cb2083b452504955daa9..6b1b3620591e5ffec8dd03df78b1615705e4b302 100644 --- a/lib_rend/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -67,11 +67,7 @@ typedef struct cldfb_convolver_state float filter_states_im[BINAURAL_CONVBANDS][CLDFB_CONVOLVER_NTAPS_MAX]; } cldfb_convolver_state; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES static void ivas_reverb_set_energies( const float *avg_pwr_l, const float *avg_pwr_r, const int32_t sampling_rate, float *avg_pwr_l_out, float *avg_pwr_r_out ); -#else -static ivas_error ivas_reverb_get_fastconv_hrtf_set_energies( const HRTFS_FASTCONV_HANDLE hHrtfFastConv, const AUDIO_CONFIG input_audio_config, const int16_t use_brir, const int32_t sampling_rate, float *avg_pwr_left, float *avg_pwr_right ); -#endif /*-----------------------------------------------------------------------------------------* * Function ivas_reverb_prepare_cldfb_params() @@ -80,15 +76,8 @@ static ivas_error ivas_reverb_get_fastconv_hrtf_set_energies( const HRTFS_FASTCO *-----------------------------------------------------------------------------------------*/ ivas_error ivas_reverb_prepare_cldfb_params( -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, const HRTFS_STATISTICS_HANDLE hHrtfStatistics, -#else - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, - const HRTFS_FASTCONV_HANDLE hHrtfFastConv, - const AUDIO_CONFIG input_audio_config, - const int16_t use_brir, -#endif const int32_t output_Fs, float *pOutput_t60, float *pOutput_ene ) @@ -100,9 +89,6 @@ ivas_error ivas_reverb_prepare_cldfb_params( float delay_diff, ln_1e6_inverted, exp_argument; const float dist = DEFAULT_SRC_DIST; const float dmx_gain_2 = 4.0f * EVS_PI * dist * dist / 0.001f; -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - ivas_error error; -#endif for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { @@ -123,14 +109,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( pOutput_ene[idx] *= expf( exp_argument ); } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left, avg_pwr_right ); -#else - if ( ( error = ivas_reverb_get_fastconv_hrtf_set_energies( hHrtfFastConv, input_audio_config, use_brir, output_Fs, avg_pwr_left, avg_pwr_right ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { @@ -140,353 +119,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( return IVAS_ERR_OK; } -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -/*-----------------------------------------------------------------------------------------* - * Function ivas_cldfb_convolver() - * - * Function for convolving CLDFB-domain data with filter taps - *-----------------------------------------------------------------------------------------*/ - -static void ivas_cldfb_convolver( - cldfb_convolver_state *convolver_state, /* i/o: pointer to convolver state structure */ - float out_CLDFB_real[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* o : real part of binaural signals */ - float out_CLDFB_imag[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* o : imag part of binaural signals */ - float in_CLDFB_real[CLDFB_NO_CHANNELS_MAX], /* i : real part of input signals */ - float in_CLDFB_imag[CLDFB_NO_CHANNELS_MAX], /* i : imag part of input signals */ - const int16_t num_conv_bands, /* i : number of convolution bands */ - const int16_t num_taps /* i : number of filter taps */ -) -{ - int16_t band_idx, tap_idx; - float *filter_states_real_ptr, *filter_states_imag_ptr; - const float *filter_taps_left_re_ptr, *filter_taps_left_im_ptr, *filter_taps_right_re_ptr, *filter_taps_right_im_ptr; - - for ( band_idx = 0; band_idx < num_conv_bands; band_idx++ ) - { - float out_real_left, out_real_right, out_imag_left, out_imag_right; - out_real_left = 0.0f; - out_real_right = 0.0f; - out_imag_left = 0.0f; - out_imag_right = 0.0f; - - filter_states_real_ptr = (float *) &( convolver_state->filter_states_re[band_idx][0] ); - filter_states_imag_ptr = (float *) &( convolver_state->filter_states_im[band_idx][0] ); - - filter_taps_left_re_ptr = convolver_state->filter_taps_left_re[band_idx]; - filter_taps_left_im_ptr = convolver_state->filter_taps_left_im[band_idx]; - filter_taps_right_re_ptr = convolver_state->filter_taps_right_re[band_idx]; - filter_taps_right_im_ptr = convolver_state->filter_taps_right_im[band_idx]; - - for ( tap_idx = num_taps - 1; tap_idx > 0; tap_idx-- ) - { - filter_states_real_ptr[tap_idx] = filter_states_real_ptr[tap_idx - 1]; - filter_states_imag_ptr[tap_idx] = filter_states_imag_ptr[tap_idx - 1]; - - /* Left real and imag */ - out_real_left += ( filter_states_real_ptr[tap_idx] * filter_taps_left_re_ptr[tap_idx] ) - ( filter_states_imag_ptr[tap_idx] * filter_taps_left_im_ptr[tap_idx] ); - out_imag_left += ( filter_states_real_ptr[tap_idx] * filter_taps_left_im_ptr[tap_idx] ) + ( filter_states_imag_ptr[tap_idx] * filter_taps_left_re_ptr[tap_idx] ); - - /* Right real and imag*/ - out_real_right += ( filter_states_real_ptr[tap_idx] * filter_taps_right_re_ptr[tap_idx] ) - ( filter_states_imag_ptr[tap_idx] * filter_taps_right_im_ptr[tap_idx] ); - out_imag_right += ( filter_states_real_ptr[tap_idx] * filter_taps_right_im_ptr[tap_idx] ) + ( filter_states_imag_ptr[tap_idx] * filter_taps_right_re_ptr[tap_idx] ); - } - - filter_states_real_ptr[0] = in_CLDFB_real[band_idx]; - filter_states_imag_ptr[0] = in_CLDFB_imag[band_idx]; - - /* Left real and imag */ - out_CLDFB_real[0][band_idx] += out_real_left + ( filter_states_real_ptr[0] * filter_taps_left_re_ptr[0] ) - ( filter_states_imag_ptr[0] * filter_taps_left_im_ptr[0] ); - out_CLDFB_imag[0][band_idx] += out_imag_left + ( filter_states_real_ptr[0] * filter_taps_left_im_ptr[0] ) + ( filter_states_imag_ptr[0] * filter_taps_left_re_ptr[0] ); - - /* Right real and imag */ - out_CLDFB_real[1][band_idx] += out_real_right + ( filter_states_real_ptr[0] * filter_taps_right_re_ptr[0] ) - ( filter_states_imag_ptr[0] * filter_taps_right_im_ptr[0] ); - out_CLDFB_imag[1][band_idx] += out_imag_right + ( filter_states_real_ptr[0] * filter_taps_right_im_ptr[0] ) + ( filter_states_imag_ptr[0] * filter_taps_right_re_ptr[0] ); - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_IR_from_filter_taps() - * - * Function converts CLDFB filter taps into time-domain data - *-----------------------------------------------------------------------------------------*/ - -static ivas_error get_IR_from_filter_taps( - const HRTFS_FASTCONV_HANDLE hHrtfFastConv, - const int16_t hrtf_idx, - const AUDIO_CONFIG input_audio_config, - const int16_t use_brir, - const int32_t sampling_rate, - const int16_t pulse_length, - float *pOut_l, - float *pOut_r ) -{ - int16_t i, j, band_idx, block_idx, block_len, block_count, input_sample_idx, output_sample_idx, array_idx; - HANDLE_CLDFB_FILTER_BANK handle_cldfb_analysis, handle_cldfb_synthesis_l, handle_cldfb_synthesis_r; - cldfb_convolver_state convolver_state; - float real_buffer_in[CLDFB_NO_CHANNELS_MAX]; - float imag_buffer_in[CLDFB_NO_CHANNELS_MAX]; - float out_CLDFB_real[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; /* o : real part of Binaural signals */ - float out_CLDFB_imag[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; /* o : imag part of Binaural signals */ - float dirac_pls[CLDFB_NO_CHANNELS_MAX + 1]; - ivas_error error; - - block_len = (int16_t) ( sampling_rate * INV_CLDFB_BANDWIDTH ); - block_count = N_INITIAL_IGNORED_FRAMES + ( pulse_length / block_len ); - - set_f( dirac_pls, 0, block_len + 1 ); - dirac_pls[0] = 1.0f; - input_sample_idx = 0; - output_sample_idx = 0; - - /* Assign CLDFB taps */ - if ( input_audio_config == IVAS_AUDIO_CONFIG_HOA3 ) - { - for ( band_idx = 0; band_idx < BINAURAL_CONVBANDS; band_idx++ ) - { - convolver_state.filter_taps_left_re[band_idx] = hHrtfFastConv->leftHRIRReal_HOA3[band_idx][hrtf_idx]; - convolver_state.filter_taps_left_im[band_idx] = hHrtfFastConv->leftHRIRImag_HOA3[band_idx][hrtf_idx]; - convolver_state.filter_taps_right_re[band_idx] = hHrtfFastConv->rightHRIRReal_HOA3[band_idx][hrtf_idx]; - convolver_state.filter_taps_right_im[band_idx] = hHrtfFastConv->rightHRIRImag_HOA3[band_idx][hrtf_idx]; - } - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_HOA2 ) - { - for ( band_idx = 0; band_idx < BINAURAL_CONVBANDS; band_idx++ ) - { - convolver_state.filter_taps_left_re[band_idx] = hHrtfFastConv->leftHRIRReal_HOA2[band_idx][hrtf_idx]; - convolver_state.filter_taps_left_im[band_idx] = hHrtfFastConv->leftHRIRImag_HOA2[band_idx][hrtf_idx]; - convolver_state.filter_taps_right_re[band_idx] = hHrtfFastConv->rightHRIRReal_HOA2[band_idx][hrtf_idx]; - convolver_state.filter_taps_right_im[band_idx] = hHrtfFastConv->rightHRIRImag_HOA2[band_idx][hrtf_idx]; - } - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_FOA ) - { - for ( band_idx = 0; band_idx < BINAURAL_CONVBANDS; band_idx++ ) - { - convolver_state.filter_taps_left_re[band_idx] = hHrtfFastConv->leftHRIRReal_FOA[band_idx][hrtf_idx]; - convolver_state.filter_taps_left_im[band_idx] = hHrtfFastConv->leftHRIRImag_FOA[band_idx][hrtf_idx]; - convolver_state.filter_taps_right_re[band_idx] = hHrtfFastConv->rightHRIRReal_FOA[band_idx][hrtf_idx]; - convolver_state.filter_taps_right_im[band_idx] = hHrtfFastConv->rightHRIRImag_FOA[band_idx][hrtf_idx]; - } - } - else - { - array_idx = 0; - if ( input_audio_config == IVAS_AUDIO_CONFIG_5_1 ) - { - array_idx = channelIndex_CICP6[hrtf_idx]; - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_7_1 ) - { - array_idx = channelIndex_CICP12[hrtf_idx]; - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_5_1_2 ) - { - array_idx = channelIndex_CICP14[hrtf_idx]; - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_5_1_4 ) - { - array_idx = channelIndex_CICP16[hrtf_idx]; - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_7_1_4 ) - { - array_idx = channelIndex_CICP19[hrtf_idx]; - } - - if ( use_brir ) - { - for ( band_idx = 0; band_idx < BINAURAL_CONVBANDS; band_idx++ ) - { - convolver_state.filter_taps_left_re[band_idx] = hHrtfFastConv->leftBRIRReal[band_idx][array_idx]; - convolver_state.filter_taps_left_im[band_idx] = hHrtfFastConv->leftBRIRImag[band_idx][array_idx]; - convolver_state.filter_taps_right_re[band_idx] = hHrtfFastConv->rightBRIRReal[band_idx][array_idx]; - convolver_state.filter_taps_right_im[band_idx] = hHrtfFastConv->rightBRIRImag[band_idx][array_idx]; - } - } - else - { - for ( band_idx = 0; band_idx < BINAURAL_CONVBANDS; band_idx++ ) - { - convolver_state.filter_taps_left_re[band_idx] = hHrtfFastConv->leftHRIRReal[band_idx][array_idx]; - convolver_state.filter_taps_left_im[band_idx] = hHrtfFastConv->leftHRIRImag[band_idx][array_idx]; - convolver_state.filter_taps_right_re[band_idx] = hHrtfFastConv->rightHRIRReal[band_idx][array_idx]; - convolver_state.filter_taps_right_im[band_idx] = hHrtfFastConv->rightHRIRImag[band_idx][array_idx]; - } - } - } - - for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) - { - for ( j = 0; j < CLDFB_CONVOLVER_NTAPS_MAX; j++ ) - { - convolver_state.filter_states_re[i][j] = 0; - convolver_state.filter_states_im[i][j] = 0; - } - } - - if ( ( error = openCldfb( &handle_cldfb_analysis, CLDFB_ANALYSIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = openCldfb( &handle_cldfb_synthesis_l, CLDFB_SYNTHESIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = openCldfb( &handle_cldfb_synthesis_r, CLDFB_SYNTHESIS, sampling_rate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Main loop for convolving dirac pulse with CLDFB filter taps */ - for ( block_idx = 0; block_idx < block_count; block_idx++ ) - { - float *ppRealBuf[1]; - float *ppImagBuf[1]; - - cldfbAnalysis_ts( &dirac_pls[input_sample_idx], real_buffer_in, imag_buffer_in, block_len, handle_cldfb_analysis ); - - /* Perform convolution */ - - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - for ( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) - { - out_CLDFB_real[i][j] = 0; - out_CLDFB_imag[i][j] = 0; - } - } - - ivas_cldfb_convolver( &convolver_state, out_CLDFB_real, out_CLDFB_imag, real_buffer_in, imag_buffer_in, BINAURAL_CONVBANDS, BINAURAL_NTAPS ); - - ppRealBuf[0] = out_CLDFB_real[0]; - ppImagBuf[0] = out_CLDFB_imag[0]; - cldfbSynthesis( ppRealBuf, ppImagBuf, &pOut_l[output_sample_idx], block_len, handle_cldfb_synthesis_l ); - - ppRealBuf[0] = out_CLDFB_real[1]; - ppImagBuf[0] = out_CLDFB_imag[1]; - cldfbSynthesis( ppRealBuf, ppImagBuf, &pOut_r[output_sample_idx], block_len, handle_cldfb_synthesis_r ); - - if ( input_sample_idx == 0 ) - { - input_sample_idx = 1; - } - - if ( block_idx >= N_INITIAL_IGNORED_FRAMES ) - { - output_sample_idx += block_len; - } - } - - deleteCldfb( &handle_cldfb_analysis ); - deleteCldfb( &handle_cldfb_synthesis_l ); - deleteCldfb( &handle_cldfb_synthesis_r ); - - return IVAS_ERR_OK; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_reverb_get_cldfb_hrtf_set_properties() - * - * Function analyses the HRTF set and computes avarage left/right power spectrum - * and frequency-dependent IA coherence. - * Uses fastconv renderer filter taps to compute energies - *-----------------------------------------------------------------------------------------*/ - -static ivas_error ivas_reverb_get_cldfb_hrtf_set_properties( - AUDIO_CONFIG input_audio_config, - const HRTFS_FASTCONV_HANDLE hHrtfFastConv, - const int16_t use_brir, - const int32_t sampling_rate, - float *avg_pwr_left, - float *avg_pwr_right ) -{ - float current_HRTF_data_L[L_FRAME48k]; - float current_HRTF_data_R[L_FRAME48k]; - int16_t freq_idx, hrtf_idx, hrtf_count; - float hrtf_count_inverted; - int16_t fft_size, IR_length, log2_fft_size, half_fft_size, freq_count; - ivas_error error; - - fft_size = RV_FILTER_MAX_FFT_SIZE; - IR_length = CLDFB_NO_CHANNELS_MAX * ( ( fft_size + CLDFB_NO_CHANNELS_MAX - 1 ) / CLDFB_NO_CHANNELS_MAX ); - log2_fft_size = int_log2( fft_size ); - half_fft_size = fft_size >> 1; - freq_count = 1 + half_fft_size; - - /* chosing between ambisonics, 5.1 and 7.1 MC audio */ - if ( ( input_audio_config == IVAS_AUDIO_CONFIG_FOA ) || ( input_audio_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( input_audio_config == IVAS_AUDIO_CONFIG_HOA3 ) ) - { - hrtf_count = 1; - } - else if ( input_audio_config == IVAS_AUDIO_CONFIG_7_1 ) - { - hrtf_count = 7; - } - else - { - hrtf_count = 5; - input_audio_config = IVAS_AUDIO_CONFIG_5_1; - } - - /* Zeroing before accumalation for average value computing */ - for ( freq_idx = 0; freq_idx < freq_count; freq_idx++ ) - { - avg_pwr_left[freq_idx] = 0.0f; - avg_pwr_right[freq_idx] = 0.0f; - } - - /* Get power spectra and cross - correlation between left and right hrtfs - Loop over all the HRTFs available */ - for ( hrtf_idx = 0; hrtf_idx < hrtf_count; hrtf_idx++ ) - { - if ( ( error = get_IR_from_filter_taps( hHrtfFastConv, hrtf_idx, input_audio_config, use_brir, sampling_rate, IR_length, current_HRTF_data_L, current_HRTF_data_R ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Perform forward FFT on both L/R channels */ - fft_rel( current_HRTF_data_L, (int16_t) fft_size, (int16_t) log2_fft_size ); - fft_rel( current_HRTF_data_R, (int16_t) fft_size, (int16_t) log2_fft_size ); - - /* Process the DC bin (without img part) */ - avg_pwr_left[0] += current_HRTF_data_L[0] * current_HRTF_data_L[0]; - avg_pwr_right[0] += current_HRTF_data_R[0] * current_HRTF_data_R[0]; - - /* Process the Nyquist frequency bin (without img part) */ - avg_pwr_left[half_fft_size] += current_HRTF_data_L[half_fft_size] * current_HRTF_data_L[half_fft_size]; - avg_pwr_right[half_fft_size] += current_HRTF_data_R[half_fft_size] * current_HRTF_data_R[half_fft_size]; - - /* Process the other frequency bins containing both real and img parts */ - for ( freq_idx = 1; freq_idx < half_fft_size; freq_idx++ ) - { - float L_re, L_im, R_re, R_im; - L_re = current_HRTF_data_L[freq_idx]; - R_re = current_HRTF_data_R[freq_idx]; - L_im = current_HRTF_data_L[fft_size - freq_idx]; - R_im = current_HRTF_data_R[fft_size - freq_idx]; - - avg_pwr_left[freq_idx] += L_re * L_re + L_im * L_im; - avg_pwr_right[freq_idx] += R_re * R_re + R_im * R_im; - } - } - - /* Compute the averages and the IA coherence */ - hrtf_count_inverted = 1.0f / (float) hrtf_count; - for ( freq_idx = 0; freq_idx < freq_count; freq_idx++ ) - { - avg_pwr_left[freq_idx] *= hrtf_count_inverted; - avg_pwr_right[freq_idx] *= hrtf_count_inverted; - } - - return IVAS_ERR_OK; -} -#endif -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES /*-----------------------------------------------------------------------------------------* * Function ivas_reverb_set_energies() * @@ -497,63 +130,25 @@ static ivas_error ivas_reverb_get_cldfb_hrtf_set_properties( static void ivas_reverb_set_energies( const float *avg_pwr_l, const float *avg_pwr_r, -#else -/*-----------------------------------------------------------------------------------------* - * Function ivas_reverb_get_fastconv_hrtf_set_energies() - * - * Function analyses the HRTF set and computes avarage left/right power spectrum. - * Uses fastconv renderer filter taps to compute energies. Output interpolated - * to CLDFB bin center frequencies - *-----------------------------------------------------------------------------------------*/ - -static ivas_error ivas_reverb_get_fastconv_hrtf_set_energies( - const HRTFS_FASTCONV_HANDLE hHrtfFastConv, - const AUDIO_CONFIG input_audio_config, - const int16_t use_brir, -#endif const int32_t sampling_rate, float *avg_pwr_left, float *avg_pwr_right ) { int16_t freq_idx; const int16_t cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - float avg_pwr_left_fft[FFT_SPECTRUM_SIZE]; - float avg_pwr_right_fft[FFT_SPECTRUM_SIZE]; -#endif float input_fc[FFT_SPECTRUM_SIZE]; float output_fc[CLDFB_NO_CHANNELS_MAX]; -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - ivas_error error; -#endif -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const int16_t avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC; for ( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ ) { input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) ); } -#else - for ( freq_idx = 0; freq_idx < FFT_SPECTRUM_SIZE; freq_idx++ ) - { - input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( FFT_SPECTRUM_SIZE - 1 ) ); - } -#endif for ( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) { output_fc[freq_idx] = (float) ( ( 2 * freq_idx + 1 ) * cldfb_freq_halfstep ); } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_reverb_interpolate_acoustic_data( avg_pwr_len, input_fc, avg_pwr_l, avg_pwr_r, CLDFB_NO_CHANNELS_MAX, output_fc, avg_pwr_left, avg_pwr_right ); -#else - if ( ( error = ivas_reverb_get_cldfb_hrtf_set_properties( input_audio_config, hHrtfFastConv, use_brir, sampling_rate, avg_pwr_left_fft, avg_pwr_right_fft ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_reverb_interpolate_acoustic_data( FFT_SPECTRUM_SIZE, input_fc, avg_pwr_left_fft, avg_pwr_right_fft, CLDFB_NO_CHANNELS_MAX, output_fc, avg_pwr_left, avg_pwr_right ); - return IVAS_ERR_OK; -#endif } diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c index b001e5656b18644be1ade80e690fa69a561bd9cf..2879476014732b60dd705370ceabaee7a76aff8e 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.h b/lib_rend/ivas_rom_TdBinauralRenderer.h index 0ed70893db3760145bf762fdb8a57ca084628f15..c79742757e5d9d401814eaea00bf0447cc1e43da 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.h +++ b/lib_rend/ivas_rom_TdBinauralRenderer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer.c index 903d46579e5e0001d8b9b6c80fb939248460a338..0d1a8ea002cacbcb08aac7ec1ffed614715b7c39 100644 --- a/lib_rend/ivas_rom_binauralRenderer.c +++ b/lib_rend/ivas_rom_binauralRenderer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_binauralRenderer.h b/lib_rend/ivas_rom_binauralRenderer.h index 97ec8f390dd0d0d2d605f5502aaf2e3d995beef2..a670aabd25bcd545b882b82d5e76f582aa2df897 100644 --- a/lib_rend/ivas_rom_binauralRenderer.h +++ b/lib_rend/ivas_rom_binauralRenderer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_binaural_crend_head.c b/lib_rend/ivas_rom_binaural_crend_head.c index a53b22773d37ad037ecb886f0f439c36f815f20a..d0d037bb111d8a2081da095b5629c2d1068abc5f 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.c +++ b/lib_rend/ivas_rom_binaural_crend_head.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_binaural_crend_head.h b/lib_rend/ivas_rom_binaural_crend_head.h index abbf51f01d857fcfdb1697e2ab1e19d1b0c8e561..b6adb5f785fc5adec6f65ee41edd1dc51e76bf2c 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.h +++ b/lib_rend/ivas_rom_binaural_crend_head.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 7dcfc4d061d620976e70e468d8eb85d7f63c57bd..90a2feb86a4f0345bd215507bf8b7c2a47980684 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index ee2f0e75dfca3318d7d292031f307b17a5012093..e39c43813781e3fe9274c4f99a256e00f7c676bc 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index f19828f74b7637c3c4334bfffdee7f82d56a1b42..adf6bec2262151dfd62beb7617d3e330ae3e8208 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -898,14 +898,7 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->num_subframes = num_subframes; ( *hCombinedOrientationData )->interpolationCoefficient = 1.0f; ( *hCombinedOrientationData )->interpolationIncrement = 1.0f; - if ( num_subframes == 1 ) - { - ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 2000; - } - else - { - ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 500; - } + ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 500; ( *hCombinedOrientationData )->lrSwitchedNext = 0; ( *hCombinedOrientationData )->lrSwitchedCurrent = 0; ( *hCombinedOrientationData )->lrSwitchInterpVal = 0.0f; @@ -1331,6 +1324,16 @@ ivas_error combine_external_and_head_orientations( } } +#ifdef DEBUG_MODE_ORIENTATION + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + dbgwrite( &hCombinedOrientationData->enableCombinedOrientation[i], sizeof( int16_t ), 1, 1, "res/dec_orientation_enabled.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].w ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_w.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].x ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_x.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].y ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_y.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].z ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_z.dat" ); + } +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; #endif diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 6fc30a4770c8ec8f36898aecd5f49d720ae76966..a463db9d807da35586578c2a0161c709cbfb2582 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index 12368f5fde5ae8a4af31a898e1e962ceef9c9336..e984eed05443521beb01938b83c0f48afe918d02 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_rend/ivas_splitRend_lcld_dec.c index 1d81dfebc9c2179a18b10524111f7f1721bf4255..9493d076af79417888b4e7ec4daef90abe10b43e 100644 --- a/lib_rend/ivas_splitRend_lcld_dec.c +++ b/lib_rend/ivas_splitRend_lcld_dec.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -51,7 +51,9 @@ ivas_error ivas_splitBinLCLDDecOpen( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, const int32_t iSampleRate, - const int16_t iChannels ) + const int16_t iChannels, + const int16_t iNumBlocks, + const int16_t iNumIterations ) { int16_t n; BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; @@ -65,7 +67,8 @@ ivas_error ivas_splitBinLCLDDecOpen( splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ splitBinLCLDDec->iChannels = iChannels; - if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels ) ) != IVAS_ERR_OK ) + + if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks ) ) != IVAS_ERR_OK ) { return error; } @@ -108,6 +111,8 @@ ivas_error ivas_splitBinLCLDDecOpen( { return error; } + splitBinLCLDDec->iNumBlocks = iNumBlocks; + splitBinLCLDDec->iNumIterations = iNumIterations; *hSplitBinLCLDDec = splitBinLCLDDec; @@ -171,7 +176,7 @@ void ivas_splitBinLCLDDecProcess( const int16_t bfi ) { int16_t k, n; - + int16_t itr; push_wmops( "ivas_splitBinLCLDDecProcess" ); assert( hSplitBinLCLDDec != NULL ); @@ -184,53 +189,56 @@ void ivas_splitBinLCLDDecProcess( #endif if ( !bfi ) { - /* Initialized with zeros....... */ - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + for ( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ ) { - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + /* Initialized with zeros....... */ + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) { - hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][k]; - hSplitBinLCLDDec->pppfDecLCLDImag[n][k] = Cldfb_Out_Imag[n][k]; - set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); - set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + for ( k = 0; k < hSplitBinLCLDDec->iNumBlocks; k++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + hSplitBinLCLDDec->pppfDecLCLDImag[n][k] = Cldfb_Out_Imag[n][hSplitBinLCLDDec->iNumBlocks * itr + k]; + set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + } } - } - DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); + DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); #ifdef CLDFB_DEBUG - printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); - int16_t writeByte = 0; - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); + int16_t writeByte = 0; + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) { - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) { - writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); - if ( writeByte != 1 ) - exit( -1 ); - writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); - if ( writeByte != 1 ) - exit( -1 ); + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + } } } - } #endif - if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) - { - /* cross-fade recovered frame into good frame */ - ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) + { + /* cross-fade recovered frame into good frame */ + ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + } } } else { /* do PLC for lost split renderer frame */ - ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); } /* save PLC state */ - ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); pop_wmops(); diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c index a0789d63a8a74d55b22c24ec605ff74bf6098372..6903989dd158a5b880c30fdd8300e3fa319b2feb 100644 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ b/lib_rend/ivas_splitRend_lcld_enc.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -51,7 +51,9 @@ ivas_error ivas_splitBinLCLDEncOpen( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, const int32_t iSampleRate, const int16_t iChannels, - const int32_t iDataRate ) + const int32_t iDataRate, + const int16_t iNumBlocks, + const int16_t iNumIterations ) { BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; ivas_error error; @@ -61,10 +63,10 @@ ivas_error ivas_splitBinLCLDEncOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - splitBinLCLDEnc->pLcld_enc = NULL; // place holder for CLDFB encoder handle + splitBinLCLDEnc->pLcld_enc = NULL; /* place holder for CLDFB encoder handle*/ splitBinLCLDEnc->iChannels = iChannels; - if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1 ) ) != IVAS_ERR_OK ) + if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1, iNumBlocks, (int16_t) CLDFB_NO_COL_MAX / iNumBlocks ) ) != IVAS_ERR_OK ) { return error; } @@ -90,6 +92,9 @@ ivas_error ivas_splitBinLCLDEncOpen( } } + splitBinLCLDEnc->iNumIterations = iNumIterations; + splitBinLCLDEnc->iNumBlocks = iNumBlocks; + #ifdef CLDFB_DEBUG splitBinLCLDEnc->numFrame = 0; char cldfbFilename[50] = "cldfb_in_ref.qmf"; @@ -158,8 +163,7 @@ void ivas_splitBinLCLDEncProcess( const int32_t available_bits, IVAS_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t iBitsWritten; - + int32_t iBitsWritten, itr, available_bits_itr, rem_itr, available_bits_local; push_wmops( "ivas_splitBinLCLDEncProcess" ); assert( hSplitBinLCLDEnc != NULL ); @@ -167,64 +171,70 @@ void ivas_splitBinLCLDEncProcess( assert( Cldfb_In_Imag != NULL ); assert( pBits != NULL ); + available_bits_local = available_bits; /* A conversion is needed for the 3d pointer interface here ........ */ - for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + for ( itr = 0; itr < hSplitBinLCLDEnc->iNumIterations; itr++ ) { - for ( int32_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) + + rem_itr = hSplitBinLCLDEnc->iNumIterations - itr; + available_bits_itr = available_bits_local / rem_itr; + + for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) { - hSplitBinLCLDEnc->pppfLCLDReal[n][k] = Cldfb_In_Real[n][k]; - hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][k]; + for ( int32_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k] = Cldfb_In_Real[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][hSplitBinLCLDEnc->iNumBlocks * itr + k]; + } } - } #ifdef CLDFB_DEBUG - int16_t readByte = 0; - for ( int16_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + int16_t readByte = 0; + for ( int16_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) { - for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) { - readByte = fread( &Cldfb_In_Real[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); - if ( readByte != 1 ) - break; - readByte = fread( &Cldfb_In_Imag[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + if ( readByte != 1 ) + break; + readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + } } } - } - if ( readByte == 1 ) - { - printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); - } - else - { - printf( "Writing zeroes...\n" ); - for ( int16_T k = 0; k < CLDFB_NO_COL_MAX; k++ ) + if ( readByte == 1 ) { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); + } + else + { + printf( "Writing zeroes...\n" ); + for ( int16_T k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) { - for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) { - hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; - hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; + hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; + } } } } - } #endif + EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits_itr, pBits ); - EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits, pBits ); - + available_bits_local -= iBitsWritten; #ifdef DEBUGGING - if ( iBitsWritten > available_bits ) - assert( iBitsWritten <= available_bits ); + assert( available_bits_local >= 0 ); #endif #ifdef CLDFB_DEBUG - printf( "Bits written = %d\n", iBitsWritten ); + printf( "Bits written = %d\n", iBitsWritten ); #endif - + } pop_wmops(); return; diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_rend/ivas_splitRendererPLC.c index 0c75b55eb6df5adc34549767aa7843ef781c0db9..299430f28ee1191c44152cf4e49f645d6ff447f4 100644 --- a/lib_rend/ivas_splitRendererPLC.c +++ b/lib_rend/ivas_splitRendererPLC.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -74,7 +74,8 @@ static void adaptive_polar_ext_plc( float xf_alp[CLDFB_PLC_XF], float xf_bet[CLDFB_PLC_XF] #endif -) + , + const int16_t iNumCols ) { float uth[CLDFB_NO_COL_MAX], uthu[CLDFB_NO_COL_MAX], urh[CLDFB_NO_COL_MAX]; float ph_adj, ph_diff, ph_adj_t, quot, drho, srho, diff, dth, sth, fac_real, fac_imag; @@ -91,7 +92,7 @@ static void adaptive_polar_ext_plc( sth = 0.0f; /* calculate per-sample phase and magnitude evolution in preceding frame */ - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + for ( k = 0; k < iNumCols; k++ ) { urh[k] = sqrtf( prev_imag[k] * prev_imag[k] + prev_real[k] * prev_real[k] ); if ( urh[k] < EPSILON ) @@ -134,14 +135,14 @@ static void adaptive_polar_ext_plc( } } - if ( k == CLDFB_NO_COL_MAX ) + if ( k == iNumCols ) { /* mean and stdev of per-sample magnitude ratios */ - drho *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); - temp = srho - ( CLDFB_NO_COL_MAX - 1 ) * SQR( drho ); + drho *= 1.0f / ( iNumCols - 1 ); + temp = srho - ( iNumCols - 1 ) * SQR( drho ); if ( temp > 0 ) { - srho = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + srho = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); } else { @@ -149,11 +150,11 @@ static void adaptive_polar_ext_plc( } /* mean and stdev of per-sample phase differences */ - dth *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); - temp = sth - ( CLDFB_NO_COL_MAX - 1 ) * SQR( dth ); + dth *= 1.0f / ( iNumCols - 1 ); + temp = sth - ( iNumCols - 1 ) * SQR( dth ); if ( temp > 0 ) { - sth = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + sth = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); } else { @@ -173,12 +174,12 @@ static void adaptive_polar_ext_plc( /* Calculate start value for evolution from last samples of previous frame */ fac_powj_real = fac_real; fac_powj_imag = fac_imag; - start_real = prev_real[CLDFB_NO_COL_MAX - 1]; - start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; + start_real = prev_real[iNumCols - 1]; + start_imag = prev_imag[iNumCols - 1]; for ( j = 1; j < START_VAL_AVG_LEN; j++ ) { - start_real += fac_powj_real * prev_real[CLDFB_NO_COL_MAX - j - 1] - fac_powj_imag * prev_imag[CLDFB_NO_COL_MAX - j - 1]; - start_imag += fac_powj_imag * prev_real[CLDFB_NO_COL_MAX - j - 1] + fac_powj_real * prev_imag[CLDFB_NO_COL_MAX - j - 1]; + start_real += fac_powj_real * prev_real[iNumCols - j - 1] - fac_powj_imag * prev_imag[iNumCols - j - 1]; + start_imag += fac_powj_imag * prev_real[iNumCols - j - 1] + fac_powj_real * prev_imag[iNumCols - j - 1]; temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; fac_powj_imag = fac_powj_imag * fac_real + fac_powj_real * fac_imag; fac_powj_real = temp; @@ -187,8 +188,8 @@ static void adaptive_polar_ext_plc( start_imag *= 1.0f / START_VAL_AVG_LEN; #else /* take last sample of previous frame as start value */ - start_real = prev_real[CLDFB_NO_COL_MAX - 1]; - start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; + start_real = prev_real[iNumCols - 1]; + start_imag = prev_imag[iNumCols - 1]; #endif #if DO_PERTURB != 0 @@ -211,7 +212,7 @@ static void adaptive_polar_ext_plc( /* apply complex evolution for first substitution sample */ rec_real[0] = rat_real * start_real - rat_imag * start_imag; rec_imag[0] = rat_imag * start_real + rat_real * start_imag; - for ( j = 2; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 2; j < iNumCols; j++ ) { /* make evolution less static: apply per samples differences as in preceding frame */ rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); @@ -244,13 +245,13 @@ static void adaptive_polar_ext_plc( #endif rat_real *= abs2inv; rat_imag *= abs2inv; - rec_real[j + CLDFB_NO_COL_MAX - 2] = rat_real * rec_real[j + CLDFB_NO_COL_MAX - 3] - rat_imag * rec_imag[j + CLDFB_NO_COL_MAX - 3]; - rec_imag[j + CLDFB_NO_COL_MAX - 2] = rat_imag * rec_real[j + CLDFB_NO_COL_MAX - 3] + rat_real * rec_imag[j + CLDFB_NO_COL_MAX - 3]; + rec_real[j + iNumCols - 2] = rat_real * rec_real[j + iNumCols - 3] - rat_imag * rec_imag[j + iNumCols - 3]; + rec_imag[j + iNumCols - 2] = rat_imag * rec_real[j + iNumCols - 3] + rat_real * rec_imag[j + iNumCols - 3]; } #else rec_real[0] = fac_real * start_real - fac_imag * start_imag; rec_imag[0] = fac_imag * start_real + fac_real * start_imag; - for ( j = 1; j < CLDFB_NO_COL_MAX + CLDFB_PLC_XF; j++ ) + for ( j = 1; j < iNumCols + CLDFB_PLC_XF; j++ ) { rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1]; rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1]; @@ -261,8 +262,8 @@ static void adaptive_polar_ext_plc( /* apply crossfade */ for ( j = 0; j < CLDFB_PLC_XF; j++ ) { - rec_real[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; - rec_imag[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; + rec_real[iNumCols + j] *= xf_alp[j]; + rec_imag[iNumCols + j] *= xf_alp[j]; xf_bet[j] = 1 - xf_alp[j]; } #endif @@ -273,7 +274,7 @@ static void adaptive_polar_ext_plc( Ruu_real[0] = SQR( prev_real[0] ) + SQR( prev_imag[0] ); Ruu_real[1] = 0; Ruu_imag[1] = 0; - for ( j = 1; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 1; j < iNumCols; j++ ) { Ruu_real[0] += SQR( prev_real[j] ) + SQR( prev_imag[j] ); Ruu_real[1] += prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1]; @@ -296,12 +297,12 @@ static void adaptive_polar_ext_plc( fac_powj_imag = fac_imag; abs_fac = sqrtf( SQR( fac_real ) + SQR( fac_imag ) ); abs_fac_powj = abs_fac; - for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 0; j < iNumCols; j++ ) { comp_fac = 1 - abs_fac_powj; - rec_real[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + + rec_real[j] = prev_real[iNumCols - 1] * fac_powj_real - prev_imag[iNumCols - 1] * fac_powj_imag + prev_real[j] * comp_fac; - rec_imag[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_real + + rec_imag[j] = prev_real[iNumCols - 1] * fac_powj_imag + prev_imag[iNumCols - 1] * fac_powj_real + prev_imag[j] * comp_fac; abs_fac_powj = abs_fac_powj * abs_fac; temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; @@ -317,8 +318,8 @@ static void adaptive_polar_ext_plc( for ( j = 0; j < CLDFB_PLC_XF; j++ ) { xf_bet[j] = 1 - abs_fac_powj; - rec_real[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag; - rec_imag[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_real; + rec_real[j + iNumCols] = rec_real[iNumCols - 1] * fac_powj_real - rec_imag[iNumCols - 1] * fac_powj_imag; + rec_imag[j + iNumCols] = rec_real[iNumCols - 1] * fac_powj_imag + rec_imag[iNumCols - 1] * fac_powj_real; abs_fac_powj = abs_fac_powj * abs_fac; temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; @@ -329,7 +330,7 @@ static void adaptive_polar_ext_plc( } else { - for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + for ( j = 0; j < iNumCols; j++ ) { rec_real[j] = prev_real[j]; rec_imag[j] = prev_imag[j]; @@ -338,8 +339,8 @@ static void adaptive_polar_ext_plc( for ( j = 0; j < CLDFB_PLC_XF; j++ ) { xf_bet[j] = 1; - rec_real[j + CLDFB_NO_COL_MAX] = 0; - rec_imag[j + CLDFB_NO_COL_MAX] = 0; + rec_real[j + iNumCols] = 0; + rec_imag[j + iNumCols] = 0; } #endif } @@ -405,12 +406,14 @@ void ivas_splitBinRendPLCsaveState( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs ) + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ) { int16_t k, n; /* Save Cldfb frame */ - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + for ( k = 0; k < ( iNumBlocks * iNumIterations ); k++ ) { for ( n = 0; n < num_chs; n++ ) { @@ -433,7 +436,9 @@ void ivas_splitBinRendPLC_xf( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs ) + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ) { int16_t n, i, k; @@ -452,8 +457,8 @@ void ivas_splitBinRendPLC_xf( #if CLDFB_PLC_XF > 0 for ( k = 0; k < CLDFB_PLC_XF; k++ ) { - Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + CLDFB_NO_COL_MAX][i]; - Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + CLDFB_NO_COL_MAX][i]; + Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + ( iNumBlocks * iNumIterations )][i]; + Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + ( iNumBlocks * iNumIterations )][i]; } #endif } @@ -473,7 +478,9 @@ void ivas_splitBinRendPLC( SPLIT_REND_PLC_HANDLE hSplitRendPLC, float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t num_chs ) + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ) { int32_t i, n, k; float fade_fac; @@ -481,6 +488,9 @@ void ivas_splitBinRendPLC( #if CLDFB_PLC_XF > 0 float xf_alp[CLDFB_PLC_XF]; #endif + int16_t iNumCols, fade_start_cntr, mute_cntr, fade_val; + + iNumCols = iNumBlocks * iNumIterations; /* Indicate that next transition will be from a bad frame */ hSplitRendPLC->prev_bfi = 1; @@ -497,7 +507,7 @@ void ivas_splitBinRendPLC( { for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + for ( k = 0; k < iNumCols; k++ ) { prev_real[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i]; prev_imag[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i]; @@ -508,9 +518,10 @@ void ivas_splitBinRendPLC( , xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i] #endif - ); + , + iNumCols ); - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + for ( k = 0; k < iNumCols; k++ ) { Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; @@ -519,7 +530,7 @@ void ivas_splitBinRendPLC( } #if CLDFB_PLC_XF > 0 - for ( k = CLDFB_NO_COL_MAX; k < CLDFB_NO_COL_MAX + CLDFB_PLC_XF; k++ ) + for ( k = iNumCols; k < iNumCols + CLDFB_PLC_XF; k++ ) { hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; @@ -530,19 +541,36 @@ void ivas_splitBinRendPLC( /* Check bf counter */ - if ( hSplitRendPLC->bf_count++ >= SR_PLC_FADE_START ) + fade_start_cntr = SR_PLC_FADE_START * CLDFB_NO_COL_MAX / iNumCols; + mute_cntr = SR_PLC_MUTE * CLDFB_NO_COL_MAX / iNumCols; + + if ( hSplitRendPLC->bf_count++ >= fade_start_cntr ) { - if ( hSplitRendPLC->bf_count < SR_PLC_MUTE ) + if ( hSplitRendPLC->bf_count < mute_cntr ) { - fade_fac = powf( 10, ( hSplitRendPLC->bf_count - SR_PLC_FADE_START ) * SR_PLC_FADE_DEGREE / 20.0f ); - v_multc( &Cldfb_RealBuffer_Binaural[0][0][0], fade_fac, &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - v_multc( &Cldfb_ImagBuffer_Binaural[0][0][0], fade_fac, &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + fade_val = ( ( hSplitRendPLC->bf_count - fade_start_cntr ) * iNumCols ) / CLDFB_NO_COL_MAX; + fade_fac = powf( 10, fade_val * SR_PLC_FADE_DEGREE / 20.0f ); + + for ( n = 0; n < num_chs; n++ ) + { + for ( k = 0; k < iNumCols; k++ ) + { + v_multc( &Cldfb_RealBuffer_Binaural[n][k][0], fade_fac, &Cldfb_RealBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + v_multc( &Cldfb_ImagBuffer_Binaural[n][k][0], fade_fac, &Cldfb_ImagBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + } + } } else { - set_zero( &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - set_zero( &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - hSplitRendPLC->bf_count = SR_PLC_MUTE; + for ( n = 0; n < num_chs; n++ ) + { + for ( k = 0; k < iNumCols; k++ ) + { + set_zero( &Cldfb_RealBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + set_zero( &Cldfb_ImagBuffer_Binaural[n][k][0], (int16_t) CLDFB_NO_CHANNELS_MAX ); + } + } + hSplitRendPLC->bf_count = mute_cntr; } } diff --git a/lib_rend/ivas_splitRendererPost.c b/lib_rend/ivas_splitRendererPost.c index 5b060eef5a470b37942bb17e8d6ab522af842a35..002229d8b8e60b584d498f59b4f0c7ff99808134 100644 --- a/lib_rend/ivas_splitRendererPost.c +++ b/lib_rend/ivas_splitRendererPost.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -1289,15 +1289,6 @@ static void interpolate_rend_md( gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; } -#if 0 - diff = gd1 / gd2; - pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); - pitch_gain_l = max( 0.0f, pitch_gain_l ); - - diff = gd3 / gd4; - pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); - pitch_gain_r = max( 0.0f, pitch_gain_r ); -#else diff = gd1 - gd2; pitch_gain_l = gd1 - ( diff * interp_pitch_fact ); pitch_gain_l = max( 0.0f, pitch_gain_l ); @@ -1305,7 +1296,6 @@ static void interpolate_rend_md( diff = gd3 - gd4; pitch_gain_r = gd3 - ( diff * interp_pitch_fact ); pitch_gain_r = max( 0.0f, pitch_gain_r ); -#endif for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) { diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index fb818cc851288b8acf8a104120c5560dd0fcaff5..25bc04dfb50dba53d411d4713ee69c5e90d3d960 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -640,69 +640,9 @@ static void ComputeCoeffs( } } -#if 0 - if ( 1 ) - { -#endif gd2 = 0.0f; sigma_d = 0.0f; hMd->gd = 0.0f; -#if 0 - } - else - { - - sigma_d = cov_ii_norm_re[0][0] + cov_ii_norm_re[1][1] + cov_ii_norm_re[0][1] + cov_ii_norm_re[1][0] + EPSILON; - - rho_hat = max( EPSILON, sqrtf( postpred_cov_re[0][0] * postpred_cov_re[1][1] ) ); - rho_hat = postpred_cov_re[0][1] / rho_hat; - rho = max( EPSILON, sqrtf( cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1] ) ); - rho = cov_oo_norm_re[0][1] / rho; - rho_hat = min( max( rho_hat, -0.9999f ), 0.9999f ); - rho = min( max( rho, -0.9999f ), 0.9999f ); - - // Compute decorrelator gain : gd2 = 0; - gd = 0; - gd2 = 0; - - aa = ( sigma_d * sigma_d ) * ( ( rho_hat * rho_hat ) - 1 ) + EPSILON; - bb = -( rho_hat * rho_hat ) * sigma_d * ( cov_oo_norm_re[0][0] + cov_oo_norm_re[1][1] ); - cc = ( rho_hat * rho_hat ) * cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1]; - cc -= cov_oo_norm_re[0][1] * cov_oo_norm_re[0][1]; - - sign = +1.0f; - if ( rho < ( rho_hat - 0.0001 ) ) - { - bb -= 2 * sigma_d * cov_oo_norm_re[0][1]; - sign = -1.0f; - } - else if ( rho > ( rho_hat + 0.0001 ) ) - { - bb += 2 * sigma_d * cov_oo_norm_re[0][1]; - } - dd = bb * bb - ( 4 * aa * cc ); - if ( dd >= 0 ) - { - float gd2_1, gd2_2; - gd2_1 = ( -bb + sqrtf( dd ) ) / ( 2 * aa ); - gd2_2 = ( -bb - sqrtf( dd ) ) / ( 2 * aa ); - if ( ( gd2_1 >= 0 ) && ( gd2_2 >= 0 ) ) - { - gd2 = min( gd2_1, gd2_2 ); - } - else - { - gd2 = max( 0, max( gd2_1, gd2_2 ) ); - } - gd = sign * sqrtf( gd2 ); - } - - gd = min( IVAS_SPLIT_REND_D_MAX_VAL, max( gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); - hMd->gd = SPLIT_REND_DECOR_ALPHA * gd + ( 1 - SPLIT_REND_DECOR_ALPHA ) * hMd->gd; - gd2 = min( gd2, cov_oo_norm_re[0][0] / sigma_d ); - gd2 = min( gd2, cov_oo_norm_re[1][1] / sigma_d ); - } -#endif /* 0 */ if ( postpred_cov_re[0][0] > EPSILON ) { @@ -1457,17 +1397,6 @@ void ivas_rend_CldfbSplitPreRendProcess( QuaternionsPost[sf_idx].z = 0.0f; } -#if 0 - read_off = pBits->bits_read; - write_off = pBits->bits_written; - ivas_splitBinPostRendMdDec( - pBits, - hBinHrSplitPreRend->hBinHrSplitPostRend, - pMultiBinPoseData ); - pMultiBinPoseData->poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - pBits->bits_read = read_off; - pBits->bits_written = write_off; -#else hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1; set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); @@ -1486,7 +1415,6 @@ void ivas_rend_CldfbSplitPreRendProcess( for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; -#if 1 BIN_HR_SPLIT_REND_MD_HANDLE hMd; hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; minv = -1.4f; @@ -1523,12 +1451,10 @@ void ivas_rend_CldfbSplitPreRendProcess( hMd->pred_mat_im[ch1][ch2] = quant_val * step; } } -#endif } } } -#endif for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { mvr2r( (float *) Cldfb_In_BinReal[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); @@ -1799,22 +1725,14 @@ static ivas_error split_renderer_open_lc3plus( SPLIT_REND_WRAPPER *hSplitRendWrapper, const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, const int32_t OutSampleRate, - const int16_t is_5ms_frame ) + const int16_t num_subframes ) { ivas_error error; int16_t i, delayBufferLength; LC3PLUS_CONFIG config; - if ( is_5ms_frame ) - { - config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; - config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us : 20000; - } - else - { - config.lc3plus_frame_duration_us = 5000; - config.ivas_frame_duration_us = 20000; - } + config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; + config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us * num_subframes : 20000; config.samplerate = OutSampleRate; config.channels = BINAURAL_CHANNELS; @@ -1878,7 +1796,7 @@ ivas_error ivas_split_renderer_open( const int32_t OutSampleRate, const int16_t cldfb_in_flag, const int16_t pcm_out_flag, - const int16_t is_5ms_frame ) + const int16_t num_subframes ) { ivas_error error, ch, num_ch; #ifndef SPLIT_REND_WITH_HEAD_ROT @@ -1985,14 +1903,17 @@ ivas_error ivas_split_renderer_open( { if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) { - if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, is_5ms_frame ) ) != IVAS_ERR_OK ) + if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, num_subframes ) ) != IVAS_ERR_OK ) { return error; } } else { - if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ) ) ) != IVAS_ERR_OK ) + int16_t iNumBlocksPerFrame; + iNumBlocksPerFrame = ( CLDFB_NO_COL_MAX * pSplitRendConfig->codec_frame_size_ms ) / 20; + + if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ), iNumBlocksPerFrame, 1 ) ) != IVAS_ERR_OK ) { return error; } @@ -2155,6 +2076,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( uint8_t useLc3plus; float *in_delayed[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; int16_t i; + int32_t num_slots; push_wmops( "ivas_renderMultiTDBinToSplitBinaural" ); @@ -2187,10 +2109,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( actual_md_bits = pBits->bits_written; if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) { - if ( !useLc3plus && codec_frame_size_ms != 20 && !pcm_out_flag ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_INPUT_BUFFER_SIZE, "Unsupported framing for LCLD codec!" ); - } + num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; /* CLDFB Analysis*/ @@ -2214,7 +2133,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( #endif for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) { cldfbAnalysis_ts( &( in_delayed[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), Cldfb_In_BinReal[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], Cldfb_In_BinImag[pos_idx * BINAURAL_CHANNELS + ch][slot_idx], @@ -2240,10 +2159,10 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( if ( !useLc3plus ) { - available_bits = SplitRendBitRate * L_FRAME48k / 48000; + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; - pBits->codec_frame_size_ms = 20; + pBits->codec_frame_size_ms = codec_frame_size_ms; ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } @@ -2270,7 +2189,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( { if ( !useLc3plus ) { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); } else { @@ -2389,11 +2308,12 @@ ivas_error ivas_renderMultiBinToSplitBinaural( /* Needs to be done at runtime. If this was in another API function, * there would be no guarantee that the user did not change * the split rendering config before calling the main rendering function */ - if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag, 0 ) ) != IVAS_ERR_OK ) { return error; } + if ( cldfb_in_flag == 0 ) { /*TD input*/ @@ -2427,23 +2347,24 @@ ivas_error ivas_renderMultiBinToSplitBinaural( if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) { - available_bits = SplitRendBitRate * L_FRAME48k / 48000; + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); actual_md_bits = pBits->bits_written - actual_md_bits; available_bits -= actual_md_bits; - + pBits->codec_frame_size_ms = codec_frame_size_ms; ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); } else { - int16_t ch, slot_idx; - + int16_t ch, slot_idx, num_slots, ivas_fs; + ivas_fs = (int16_t) hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + num_slots = (int16_t) ( CLDFB_NO_COL_MAX * ivas_fs ) / 20; /* CLDFB synthesis of main pose */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) { Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[ch][slot_idx]; Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[ch][slot_idx]; @@ -2451,7 +2372,7 @@ ivas_error ivas_renderMultiBinToSplitBinaural( #ifndef SPLIT_REND_WITH_HEAD_ROT cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); #else - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); #endif } @@ -2488,7 +2409,6 @@ ivas_error ivas_renderMultiBinToSplitBinaural( } /*zero pad*/ - /*TODO: do this inside the LCLD ENC codec */ if ( pcm_out_flag ) { bit_len = SplitRendBitRate / FRAMES_PER_SEC; @@ -2497,7 +2417,7 @@ ivas_error ivas_renderMultiBinToSplitBinaural( { if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); } else { diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c index daf6eb6f28066e8a8ad82c93769c21b41d7f1944..da9ba62801bda41292f9cdcb08695b481fd19de4 100644 --- a/lib_rend/ivas_splitRenderer_utils.c +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -724,7 +724,7 @@ ivas_error ivas_split_rend_validate_config( if ( pSplitRendConfig->codec_frame_size_ms != 0 ) /* 0 means "default for current codec", will be set to actual value at a later stage */ { - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 20 ) + if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 5 && pSplitRendConfig->codec_frame_size_ms != 10 && pSplitRendConfig->codec_frame_size_ms != 20 ) { return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); } @@ -1053,7 +1053,8 @@ ivas_error ivas_split_rend_choose_default_codec( IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ - const int16_t pcm_out_flag /* i : flag to indicate PCM output */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t num_subframes /* i : number of subframes */ ) { if ( pcm_out_flag == 0 ) @@ -1073,7 +1074,7 @@ ivas_error ivas_split_rend_choose_default_codec( switch ( *pCodec ) { case IVAS_SPLIT_REND_CODEC_LCLD: - *pCodec_frame_size_ms = 20; + *pCodec_frame_size_ms = num_subframes * 5; break; case IVAS_SPLIT_REND_CODEC_LC3PLUS: case IVAS_SPLIT_REND_CODEC_NONE: @@ -1087,3 +1088,16 @@ ivas_error ivas_split_rend_choose_default_codec( return IVAS_ERR_OK; } #endif + +/*-------------------------------------------------------------------* + * Function get_bit() + * + * + *-------------------------------------------------------------------*/ + +int32_t get_bit( + const int32_t state, + const int32_t bit_id ) +{ + return ( state & ( 1 << bit_id ) ); +} diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index e95ff21a38d4d31534b6dc3b2da882a57ddda719..672f2642119b7153f3d589794f208e8714600508 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -500,6 +500,17 @@ typedef struct ivas_diffuse_distribution_data_structure } DIFFUSE_DISTRIBUTION_DATA, *DIFFUSE_DISTRIBUTION_HANDLE; +/* Parametric binaural renderer HRTF structure */ +typedef struct ivas_hrtfs_parambin_struct +{ + float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; + float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; + + float parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX]; + float parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX]; + float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; + +} HRTFS_PARAMBIN, *HRTFS_PARAMBIN_HANDLE; /* Parametric binaural data structure */ typedef struct ivas_dirac_dec_binaural_data_structure @@ -536,6 +547,8 @@ typedef struct ivas_dirac_dec_binaural_data_structure ivas_td_decorr_state_t *hTdDecorr; float reqularizationFactor; + HRTFS_PARAMBIN_HANDLE *phHrtfParambin; + DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist; HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params; @@ -1063,11 +1076,6 @@ typedef struct TDREND_HRFILT_FiltSet_struct ModelParamsITD_t ModelParamsITD; TDREND_HRFILT_Method_t FilterMethod; /* HR filtering method */ float latency_s; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -#else - const float *lr_energy_and_iac[3]; /* left/right energy and interaural coherence for late reverb */ - float *lr_energy_and_iac_dyn[3]; -#endif } TDREND_HRFILT_FiltSet_t; @@ -1319,18 +1327,7 @@ typedef struct ivas_hrtfs_fastconv_struct } HRTFS_FASTCONV, *HRTFS_FASTCONV_HANDLE; -typedef struct ivas_hrtfs_parambin_struct -{ - float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; - float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; - - float parametricReverberationTimes[CLDFB_NO_CHANNELS_MAX]; - float parametricReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX]; - float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; -} HRTFS_PARAMBIN, *HRTFS_PARAMBIN_HANDLE; - -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES typedef struct ivas_hrtfs_statistics_struct { float *average_energy_l; @@ -1338,7 +1335,6 @@ typedef struct ivas_hrtfs_statistics_struct float *inter_aural_coherence; int16_t fromROM; /* Flag that indicates that the pointers point to tables in ROM (controls init/dealloc).*/ } HRTFS_STATISTICS, *HRTFS_STATISTICS_HANDLE; -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT /*----------------------------------------------------------------------------------* @@ -1443,6 +1439,8 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct FILE *cldfbIn; int16_t numFrame; #endif + int16_t iNumIterations; + int16_t iNumBlocks; } BIN_HR_SPLIT_LCLD_ENC, *BIN_HR_SPLIT_LCLD_ENC_HANDLE; @@ -1476,6 +1474,8 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct int16_t numFrame; #endif SPLIT_REND_PLC_HANDLE hSplitRendPLC; + int16_t iNumBlocks; + int16_t iNumIterations; } BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; diff --git a/lib_rend/ivas_td_decorr.c b/lib_rend/ivas_td_decorr.c index beff2ae367bd5079ab4959f357818251e6c95014..eed6d22457bbb6d66ef047aa23a0c1938c39c212 100644 --- a/lib_rend/ivas_td_decorr.c +++ b/lib_rend/ivas_td_decorr.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/ivas_vbap.c b/lib_rend/ivas_vbap.c index 602d64df6890670bccee4c2d6a8e6d28ffdf257a..025e7398d1fbe3f652a5888054047e124889f78d 100644 --- a/lib_rend/ivas_vbap.c +++ b/lib_rend/ivas_vbap.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index d107f0216e54d76b990211d1a12f845e6ef0fd1d..a6ddac23a9ccd562ac7b1b3671447f9a3479ff86 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -229,9 +229,7 @@ typedef struct hrtf_handles IVAS_DEC_HRTF_FASTCONV_HANDLE hHrtfFastConv; IVAS_DEC_HRTF_PARAMBIN_HANDLE hHrtfParambin; IVAS_DEC_HRTF_HANDLE hHrtfTD; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics; -#endif } hrtf_handles; struct IVAS_REND @@ -280,11 +278,7 @@ struct IVAS_REND * Local function prototypes *-------------------------------------------------------------------*/ -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG outConfig, const RENDER_CONFIG_DATA *hRendCfg, hrtf_handles *hHrtfs ); -#else -static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG outConfig, hrtf_handles *hHrtfs ); -#endif static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); @@ -1416,11 +1410,7 @@ static ivas_error setRendInputActiveIsm( #endif { #ifndef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hSetOfHRTF, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1460,11 +1450,7 @@ static ivas_error setRendInputActiveIsm( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), hrtfs->hHrtfStatistics, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), outConfig, NULL, inputIsm->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1477,22 +1463,14 @@ static ivas_error setRendInputActiveIsm( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), hrtfs->hHrtfStatistics, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), outConfig, NULL, inputIsm->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } } else if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hSetOfHRTF, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2179,9 +2157,7 @@ static ivas_error initMcBinauralRendering( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, IVAS_DEC_HRTF_CREND_HANDLE hMixconv, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES HRTFS_STATISTICS_HANDLE hHrtfStatistics, -#endif uint8_t reconfigureFlag ) { ivas_error error; @@ -2278,11 +2254,7 @@ static ivas_error initMcBinauralRendering( #endif if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && inputMc->hReverb == NULL ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_reverb_open( &( inputMc->hReverb ), hHrtfStatistics, hRendCfg, outSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_reverb_open( &( inputMc->hReverb ), outConfig, NULL, inputMc->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac, hRendCfg, outSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2292,19 +2264,10 @@ static ivas_error initMcBinauralRendering( { /* open CREND */ #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, outSampleRate, ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) ? inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, hMixconv, - outSampleRate, ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) ? inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 ) ) != IVAS_ERR_OK ) -#endif -#else -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, outSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, hMixconv, outSampleRate ) ) != IVAS_ERR_OK ) -#endif #endif { return error; @@ -2505,11 +2468,7 @@ static ivas_error setRendInputActiveMc( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) #endif { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, FALSE ) ) != IVAS_ERR_OK ) -#else - if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, hrtfs->hSetOfHRTF, FALSE ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2704,12 +2663,8 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, - IVAS_DEC_HRTF_CREND_HANDLE hMixconv -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - , - IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics -#endif -) + IVAS_DEC_HRTF_CREND_HANDLE hMixconv, + IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics ) { ivas_error error; AUDIO_CONFIG inConfig; @@ -2769,17 +2724,9 @@ static ivas_error updateSbaPanGains( #endif { #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, hMixconv, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#endif -#else -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, hMixconv, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif #endif { return error; @@ -2794,17 +2741,9 @@ static ivas_error updateSbaPanGains( } #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hMixconv, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) -#endif -#else -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hMixconv, hHrtfStatistics, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hMixconv, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif #endif { return error; @@ -2960,11 +2899,7 @@ static ivas_error setRendInputActiveSba( } } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = updateSbaPanGains( inputSba, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics ) ) != IVAS_ERR_OK ) -#else - if ( ( error = updateSbaPanGains( inputSba, outConfig, hRendCfg, hrtfs->hSetOfHRTF ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -3039,12 +2974,7 @@ static ivas_error setRendInputActiveMasa( const AUDIO_CONFIG inConfig, const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg, - hrtf_handles *hrtfs -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -) -#else - ) /* Todo: This is not used at all within MASA. Support might be better to do after refactoring. */ -#endif + hrtf_handles *hrtfs ) { ivas_error error; rendering_context rendCtx; @@ -3055,9 +2985,6 @@ static ivas_error setRendInputActiveMasa( inputMasa = (input_masa *) input; rendCtx = inputMasa->base.ctx; outConfig = *rendCtx.pOutConfig; -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - (void) hRendCfg; /* Suppress warning */ -#endif if ( !isIoConfigPairSupported( inConfig, outConfig ) ) { @@ -3085,11 +3012,7 @@ static ivas_error setRendInputActiveMasa( } else { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = initMasaExtRenderer( inputMasa, outConfig, hRendCfg, hrtfs ) ) != IVAS_ERR_OK ) -#else - if ( ( error = initMasaExtRenderer( inputMasa, outConfig, hrtfs ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -3117,7 +3040,6 @@ static void clearInputMasa( return; } - #ifdef SPLIT_REND_WITH_HEAD_ROT static ivas_error initSplitRend( SPLIT_REND_WRAPPER *pSplitRendWrapper, @@ -3127,7 +3049,7 @@ static ivas_error initSplitRend( const int32_t outputSampleRate, const AUDIO_CONFIG outConfig, const int16_t cldfb_in_flag, - const int16_t is_5ms_frame ) + const int16_t num_subframes ) { ivas_error error; IVAS_REND_AudioBufferConfig bufConfig; @@ -3143,7 +3065,7 @@ static ivas_error initSplitRend( ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); } - if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, is_5ms_frame ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -3356,9 +3278,7 @@ ivas_error IVAS_REND_Open( hIvasRend->hHrtfs.hHrtfParambin = NULL; hIvasRend->hHrtfs.hHrtfTD = NULL; hIvasRend->hHrtfs.hSetOfHRTF = NULL; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES hIvasRend->hHrtfs.hHrtfStatistics = NULL; -#endif if ( asHrtfBinary ) { if ( ( error = ivas_HRTF_binary_open( &( hIvasRend->hHrtfs.hHrtfTD ) ) ) != IVAS_ERR_OK ) @@ -3377,19 +3297,15 @@ ivas_error IVAS_REND_Open( { return error; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_HRTF_statistics_binary_open( &( hIvasRend->hHrtfs.hHrtfStatistics ) ) ) != IVAS_ERR_OK ) { return error; } -#endif } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_HRTF_statistics_init( &( hIvasRend->hHrtfs.hHrtfStatistics ), hIvasRend->sampleRateOut ) ) != IVAS_ERR_OK ) { return error; } -#endif return IVAS_ERR_OK; } @@ -3535,11 +3451,7 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( continue; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig, hIvasRend->hRendererConfig, NULL, NULL ) ) != IVAS_ERR_OK ) -#else - if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig, hIvasRend->hRendererConfig, NULL ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -3880,12 +3792,12 @@ ivas_error IVAS_REND_AddInput( int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -4007,9 +3919,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( hIvasRend->outputConfig, hIvasRend->hRendererConfig, hIvasRend->hHrtfs.hSetOfHRTF, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES hIvasRend->hHrtfs.hHrtfStatistics, -#endif FALSE ) ) != IVAS_ERR_OK ) { return error; @@ -4367,6 +4277,10 @@ ivas_error IVAS_REND_GetDelay( { latency_ns += IVAS_FB_DEC_DELAY_NS; } + else if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } max_latency_ns = max( max_latency_ns, latency_ns ); } } @@ -4758,12 +4672,12 @@ int16_t IVAS_REND_FeedRenderConfig( cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -4854,9 +4768,7 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->outputConfig, hIvasRend->hRendererConfig, hIvasRend->hHrtfs.hSetOfHRTF, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES hIvasRend->hHrtfs.hHrtfStatistics, -#endif TRUE ) ) != IVAS_ERR_OK ) { return error; @@ -4922,9 +4834,7 @@ ivas_error IVAS_REND_DisableHeadRotation( hIvasRend->outputConfig, hIvasRend->hRendererConfig, hIvasRend->hHrtfs.hSetOfHRTF, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES hIvasRend->hHrtfs.hHrtfStatistics, -#endif TRUE ) ) != IVAS_ERR_OK ) { return error; @@ -6948,6 +6858,8 @@ static ivas_error renderSplitBinauralWithPostRot( int16_t outBufNumSamplesPerChannel, outBufNumColPerChannel; int16_t numSamplesPerChannelCacheSize, numColPerChannelCacheSize; float *readPtr, *writePtr; + LC3PLUS_CONFIG config; + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; isPostRendInputCldfb = 0; push_wmops( "renderSplitBinauralWithPostRot" ); @@ -6957,30 +6869,48 @@ static ivas_error renderSplitBinauralWithPostRot( hSplitBin = &splitBinInput->splitPostRendWrapper; convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) + config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; + if ( pCombinedOrientationData->num_subframes != MAX_PARAM_SPATIAL_SUBFRAMES ) { - if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) { - return error; + config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us * pCombinedOrientationData->num_subframes : 20000; } - } - else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) - { - LC3PLUS_CONFIG config; - - if ( outAudio.config.numSamplesPerChannel == 240 ) + else { - config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; } - else + iNumLCLDIterationsPerFrame = 1; + } + else + { + config.ivas_frame_duration_us = 20000; + } + + if ( bits.codec_frame_size_ms > 0 ) + { + iNumLCLDIterationsPerFrame = (int16_t) config.ivas_frame_duration_us / ( 1000 * bits.codec_frame_size_ms ); + iNumLCLDIterationsPerFrame = max( 1, iNumLCLDIterationsPerFrame ); + iNumBlocksPerFrame = CLDFB_NO_COL_MAX * bits.codec_frame_size_ms / 20; + } + else + { + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + } + + config.channels = BINAURAL_CHANNELS; + config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; + + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) + { + if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS, iNumBlocksPerFrame, iNumLCLDIterationsPerFrame ) ) != IVAS_ERR_OK ) { - config.lc3plus_frame_duration_us = 5000; - config.ivas_frame_duration_us = 20000; + return error; } - config.channels = BINAURAL_CHANNELS; - config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; - + } + else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) + { if ( ( error = IVAS_LC3PLUS_DEC_Open( config, &splitBinInput->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) { @@ -7024,13 +6954,12 @@ static ivas_error renderSplitBinauralWithPostRot( { isPostRendInputCldfb = 1; } - - preRendFrameSize_ms = bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ? (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us ) / 1000 : 20; + preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000; numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; - numColPerChannelCacheSize = CLDFB_NO_COL_MAX - outBufNumColPerChannel; + numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) { @@ -7053,7 +6982,7 @@ static ivas_error renderSplitBinauralWithPostRot( /* cache the remaining 15ms */ splitBinInput->numCachedSamples = numColPerChannelCacheSize; writePtr = splitBinInput->bufferData; - for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) { for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) { @@ -7121,6 +7050,17 @@ static ivas_error renderSplitBinauralWithPostRot( else { copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + if ( splitBinInput->numCachedSamples == 0 ) + { + preRendFrameSize_ms = (int16_t) ( config.ivas_frame_duration_us ) / 1000; + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * preRendFrameSize_ms / 1000 ); + numSamplesPerChannelCacheSize -= outAudio.config.numSamplesPerChannel; + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + } + else + { + splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; + } } /* apply pose correction if enabled */ @@ -8485,11 +8425,9 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag; - - if ( hIvasRend->hRendererConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && - ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) { - hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms * hIvasRend->num_subframes * (int16_t) ( hIvasRend->sampleRateOut / 1000 ); + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = outAudio.config.numSamplesPerChannel; } else { @@ -8599,9 +8537,7 @@ void IVAS_REND_Close( ivas_HRTF_CRend_binary_close( &( hIvasRend->hHrtfs.hSetOfHRTF ) ); ivas_HRTF_fastconv_binary_close( &( hIvasRend->hHrtfs.hHrtfFastConv ) ); ivas_HRTF_parambin_binary_close( &( hIvasRend->hHrtfs.hHrtfParambin ) ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_HRTF_statistics_close( &( hIvasRend->hHrtfs.hHrtfStatistics ) ); -#endif free( hIvasRend ); *phIvasRend = NULL; @@ -8843,7 +8779,6 @@ ivas_error IVAS_REND_GetHrtfParamBinHandle( return IVAS_ERR_OK; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES /*---------------------------------------------------------------------* * IVAS_REND_GetHrtfStatisticsHandle( ) * @@ -8864,7 +8799,6 @@ ivas_error IVAS_REND_GetHrtfStatisticsHandle( return IVAS_ERR_OK; } -#endif static ivas_error ivas_masa_ext_rend_dirac_rend_init( input_masa *inputMasa ) @@ -9227,17 +9161,13 @@ static ivas_error ivas_masa_ext_rend_dirac_rend_init( } static ivas_error ivas_masa_ext_rend_parambin_init( -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES input_masa *inputMasa, /* i/o: MASA external renderer structure */ const RENDER_CONFIG_DATA *hRendCfg, /* i : Renderer configuration data handle */ HRTFS_STATISTICS_HANDLE hHrtfStatistics /* i : HRTF statistics */ -#else - input_masa *inputMasa /* i/o: MASA external renderer structure */ -#endif ) { DIRAC_DEC_BIN_HANDLE hDiracDecBin; - HRTFS_PARAMBIN_HANDLE hHrtfParambin; + HRTFS_PARAMBIN_HANDLE *phHrtfParambin; int16_t nBins; int32_t output_Fs; RENDERER_TYPE renderer_type; @@ -9251,7 +9181,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( error = IVAS_ERR_OK; - hHrtfParambin = *( inputMasa->hMasaExtRend->hHrtfParambin ); + phHrtfParambin = inputMasa->hMasaExtRend->hHrtfParambin; /* Set common variables and defaults */ output_Fs = *( inputMasa->base.ctx.pOutSampleRate ); @@ -9321,7 +9251,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( } else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */ { - mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); + mvr2r( ( *phHrtfParambin )->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); #ifdef SPLIT_REND_WITH_HEAD_ROT if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ @@ -9329,12 +9259,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( if ( hDiracDecBin->hReverb == NULL ) #endif { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRendCfg->roomAcoustics ), output_Fs, hHrtfParambin->parametricReverberationTimes, hHrtfParambin->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) -#else - /* Todo Philips: Room acoustics should be passed here once the underlying part works. In this case, it probably should come from render context or somewhere else suitable. */ - if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ) != IVAS_ERR_OK ) -#endif + if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( hRendCfg->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK ) { return error; } @@ -9375,6 +9300,8 @@ static ivas_error ivas_masa_ext_rend_parambin_init( /* External renderer uses constant regularization factor */ hDiracDecBin->reqularizationFactor = 0.4f; + hDiracDecBin->phHrtfParambin = phHrtfParambin; + #ifdef SPLIT_REND_WITH_HEAD_ROT inputMasa->hMasaExtRend->hDiracDecBin[pos_idx] = hDiracDecBin; } @@ -9388,9 +9315,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG outConfig, -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES const RENDER_CONFIG_DATA *hRendCfg, -#endif hrtf_handles *hrtfs ) { int16_t i; @@ -9516,11 +9441,7 @@ static ivas_error initMasaExtRenderer( } } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( ( error = ivas_masa_ext_rend_parambin_init( inputMasa, hRendCfg, hrtfs->hHrtfStatistics ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_masa_ext_rend_parambin_init( inputMasa ) ) != IVAS_ERR_OK ) -#endif { return error; } diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index ff5536299e2e66719deb571a6e6d722d496cacc1..a670e75af2108c83450e4066dea57a2c43769b23 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -220,12 +220,10 @@ ivas_error IVAS_REND_GetHrtfParamBinHandle( IVAS_DEC_HRTF_PARAMBIN_HANDLE **hHrtfParambin /* o : Parametric binauralizer HRTF handle */ ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES ivas_error IVAS_REND_GetHrtfStatisticsHandle( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ IVAS_DEC_HRTF_STATISTICS_HANDLE **hHrtfStatistics /* o : HRTF statistics handle */ ); -#endif /* Functions to be called during rendering */ diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index 4f6bd0c34d13fd62439775d31933f9d67a4197f4..ff9a9b33bea53240938fac15d58be6ed1766cd4e 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/audio_file_reader.h b/lib_util/audio_file_reader.h index 0fd4da5ac76c25285d3b49d67166ce651a96eeb8..051db499dfcf9bdbfaf31100eb4fae534901793c 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/audio_file_writer.c b/lib_util/audio_file_writer.c index 0ed64d02c59f8a5b3a19c74c9e4986895ad6c5f1..0f2f5335d785438e2e743e86a32aa5643921d3e6 100644 --- a/lib_util/audio_file_writer.c +++ b/lib_util/audio_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/audio_file_writer.h b/lib_util/audio_file_writer.h index b5157ffde43f74a15803ec132814992a4fb8ce8f..0b1c3315f23279a176e481743e88d2d31466f599 100644 --- a/lib_util/audio_file_writer.h +++ b/lib_util/audio_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/bitstream_reader.c b/lib_util/bitstream_reader.c index 2e88746c035759f530bb75f7940ae84990ff4de3..c8a9351c291a9443e49e04d65e87b5c27e0a27f1 100644 --- a/lib_util/bitstream_reader.c +++ b/lib_util/bitstream_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/bitstream_reader.h b/lib_util/bitstream_reader.h index 374c19d436d9db0f48a599a3acc78ab5e23489ae..2d0db4d99de4c97073c7aaecc28b791fae23294b 100644 --- a/lib_util/bitstream_reader.h +++ b/lib_util/bitstream_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/bitstream_writer.c b/lib_util/bitstream_writer.c index 7862ff1977c840601d39065c173eecf32674d290..d19a05898d620e82c40288b1f40ba6717793d327 100644 --- a/lib_util/bitstream_writer.c +++ b/lib_util/bitstream_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/bitstream_writer.h b/lib_util/bitstream_writer.h index a855f347d272e09d8996e4540154c580ba29cefb..b0fab9e44902ef2b903fbbeb6e6bbed5fbc31c08 100644 --- a/lib_util/bitstream_writer.h +++ b/lib_util/bitstream_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/cmdl_tools.c b/lib_util/cmdl_tools.c index b0b7e906cca95b1bb64e66a62677ec1ef1eb21e9..337583ab9fd5f978cc32c2b22348e2bf6a8490bb 100644 --- a/lib_util/cmdl_tools.c +++ b/lib_util/cmdl_tools.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/cmdl_tools.h b/lib_util/cmdl_tools.h index b160473002930dd2c980d9bfbdcfb8e1bad3722a..7c3c05ba16b5265d220c9fa16bab84870e375791 100644 --- a/lib_util/cmdl_tools.h +++ b/lib_util/cmdl_tools.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/cmdln_parser.c b/lib_util/cmdln_parser.c index 7fc325c0e0b038d7bbfdb467dca6e99a28850baf..02670c5aa8426844cac2e7def6bc010c1097a743 100644 --- a/lib_util/cmdln_parser.c +++ b/lib_util/cmdln_parser.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/cmdln_parser.h b/lib_util/cmdln_parser.h index b8c8370eb4e7efbfa3c6da5a1c2c661510bb1a89..4721d968f4e35d28a19eae79d71a60f7fa095bd0 100644 --- a/lib_util/cmdln_parser.h +++ b/lib_util/cmdln_parser.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/evs_rtp_payload.c b/lib_util/evs_rtp_payload.c index d67aebd4c0f4312f523e17cb74d1549fe5148bb6..c122716f3110a7ca183af914c9b173ba6ac85a6b 100644 --- a/lib_util/evs_rtp_payload.c +++ b/lib_util/evs_rtp_payload.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/evs_rtp_payload.h b/lib_util/evs_rtp_payload.h index dac5fb0e35cfee6fca7fc2402b75bf6ae94c0f42..004ecf79b695ebfff70c8f0ea69e81c44a8aaf65 100644 --- a/lib_util/evs_rtp_payload.h +++ b/lib_util/evs_rtp_payload.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/g192.c b/lib_util/g192.c index 04ba16c369a2d556562544186b70cc23ddab3b27..bec637464fd400721ef093f42ef819aa9ab2338e 100644 --- a/lib_util/g192.c +++ b/lib_util/g192.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/g192.h b/lib_util/g192.h index 9e5e56d223c4a350b9e7f6d1775c6c3364101ef0..6d6104d45327ffea1aaa885b2af085783bd9f287 100644 --- a/lib_util/g192.h +++ b/lib_util/g192.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 3d455495e0f9ffaa4e8a36e9d0afd1bb3944d77e..813a3dfc27c32c2a3082ca8249920f5aac2e6908 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -436,87 +436,6 @@ static ivas_error LoadBSplineBinary( } -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -/*-------------------------------------------------------------------* - * set_default_reverb_iac_energy() - * - * Loads reverb data from file. - --------------------------------------------------------------------*/ - -static ivas_error set_default_reverb_iac_energy( - IVAS_DEC_HRTF_HANDLE HrFiltSet_p /* i/o: HR filter model parameter structure */ -) -{ - int16_t i; - int16_t lr_iac_len; - - if ( HrFiltSet_p == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - lr_iac_len = LR_IAC_LENGTH_NR_FC; - if ( HrFiltSet_p->SampleRate == 16000 ) - { - lr_iac_len = LR_IAC_LENGTH_NR_FC_16KHZ; - } - - if ( HrFiltSet_p->ModelParams.modelROM == 0 ) - { - for ( i = 0; i < 3; i++ ) - { - HrFiltSet_p->lr_energy_and_iac_dyn[i] = (float *) malloc( lr_iac_len * sizeof( float ) ); - if ( HrFiltSet_p->lr_energy_and_iac_dyn[i] == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for hrtf data" ); - } - } - switch ( HrFiltSet_p->SampleRate ) - { - case 48000: - mvr2r( defaultHRIR_left_avg_power_48kHz, HrFiltSet_p->lr_energy_and_iac_dyn[0], LR_IAC_LENGTH_NR_FC ); - mvr2r( defaultHRIR_right_avg_power_48kHz, HrFiltSet_p->lr_energy_and_iac_dyn[1], LR_IAC_LENGTH_NR_FC ); - mvr2r( defaultHRIR_coherence_48kHz, HrFiltSet_p->lr_energy_and_iac_dyn[2], LR_IAC_LENGTH_NR_FC ); - break; - case 32000: - mvr2r( defaultHRIR_left_avg_power_32kHz, HrFiltSet_p->lr_energy_and_iac_dyn[0], LR_IAC_LENGTH_NR_FC ); - mvr2r( defaultHRIR_right_avg_power_32kHz, HrFiltSet_p->lr_energy_and_iac_dyn[1], LR_IAC_LENGTH_NR_FC ); - mvr2r( defaultHRIR_coherence_32kHz, HrFiltSet_p->lr_energy_and_iac_dyn[2], LR_IAC_LENGTH_NR_FC ); - break; - case 16000: - mvr2r( defaultHRIR_left_avg_power_16kHz, HrFiltSet_p->lr_energy_and_iac_dyn[0], lr_iac_len ); - mvr2r( defaultHRIR_right_avg_power_16kHz, HrFiltSet_p->lr_energy_and_iac_dyn[1], lr_iac_len ); - mvr2r( defaultHRIR_coherence_16kHz, HrFiltSet_p->lr_energy_and_iac_dyn[2], lr_iac_len ); - break; - } - } - else - { - switch ( HrFiltSet_p->SampleRate ) - { - case 48000: - HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_48kHz; - HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_48kHz; - HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_48kHz; - break; - case 32000: - HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_32kHz; - HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_32kHz; - HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_32kHz; - break; - case 16000: - HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_16kHz; - HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_16kHz; - HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_16kHz; - break; - } - } - - return IVAS_ERR_OK; -} -#endif - - /*-------------------------------------------------------------------* * load_reverb_from_binary() * @@ -524,18 +443,11 @@ static ivas_error set_default_reverb_iac_energy( --------------------------------------------------------------------*/ static ivas_error load_reverb_from_binary( -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics, /* i/o: HRTF statistics handle */ int32_t sampleRate, /* i : sample rate */ -#else - IVAS_DEC_HRTF_HANDLE HrFiltSet_p, /* i/o: HR filter model parameter structure */ -#endif - FILE *f_hrtf /* i : HR filter data file handle */ + FILE *f_hrtf /* i : HR filter data file handle */ ) { -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - int16_t i; -#endif bool is_reverb; ivas_error header_check_result; ivas_hrtfs_file_header_t hrtfs_file_header; @@ -545,21 +457,13 @@ static ivas_error load_reverb_from_binary( char *hrtf_data; int16_t lr_iac_len; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( hHrtfStatistics == NULL ) -#else - if ( HrFiltSet_p == NULL ) -#endif { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } lr_iac_len = LR_IAC_LENGTH_NR_FC; -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES if ( sampleRate == 16000 ) -#else - if ( HrFiltSet_p->SampleRate == 16000 ) -#endif { lr_iac_len = LR_IAC_LENGTH_NR_FC_16KHZ; } @@ -616,7 +520,6 @@ static ivas_error load_reverb_from_binary( if ( is_reverb ) { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES hHrtfStatistics->average_energy_l = (float *) malloc( lr_iac_len * sizeof( float ) ); hHrtfStatistics->average_energy_r = (float *) malloc( lr_iac_len * sizeof( float ) ); hHrtfStatistics->inter_aural_coherence = (float *) malloc( lr_iac_len * sizeof( float ) ); @@ -630,29 +533,9 @@ static ivas_error load_reverb_from_binary( fread( hHrtfStatistics->inter_aural_coherence, sizeof( const float ), lr_iac_len, f_hrtf ); hHrtfStatistics->fromROM = FALSE; -#else - /* left/right energy and interaural coherence for late reverb */ - for ( i = 0; i < 3; i++ ) - { - HrFiltSet_p->lr_energy_and_iac_dyn[i] = (float *) malloc( lr_iac_len * sizeof( float ) ); - if ( HrFiltSet_p->lr_energy_and_iac_dyn[i] == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for hrtf data" ); - } - fread( HrFiltSet_p->lr_energy_and_iac_dyn[i], sizeof( const float ), lr_iac_len, f_hrtf ); - HrFiltSet_p->lr_energy_and_iac[i] = (const float *) HrFiltSet_p->lr_energy_and_iac_dyn[i]; - } -#endif } else { -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES -#else - if ( ( header_check_result = set_default_reverb_iac_energy( HrFiltSet_p ) ) != IVAS_ERR_OK ) - { - return header_check_result; - } -#endif return IVAS_ERR_BINARY_FILE_WITHOUT_BINAURAL_RENDERER_DATA; } @@ -666,22 +549,14 @@ static ivas_error load_reverb_from_binary( *---------------------------------------------------------------------*/ ivas_error load_reverb_binary( -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics, /* i/o: HRTF statistics handle */ int32_t sampleRate, /* i : sample rate */ -#else - IVAS_DEC_HRTF_HANDLE hHrtf, /* i/o: HRTF handle */ -#endif - const hrtfFileReader *hrtfReader /* i/o: pointer to hrtfFileReader handle */ + const hrtfFileReader *hrtfReader /* i/o: pointer to hrtfFileReader handle */ ) { fseek( hrtfReader->file, 0, SEEK_SET ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES return load_reverb_from_binary( hHrtfStatistics, sampleRate, hrtfReader->file ); -#else - return load_reverb_from_binary( hHrtf, hrtfReader->file ); -#endif } @@ -933,13 +808,6 @@ void destroy_td_hrtf( free( ( *hHrtf )->ModelEval.hrfModL ); free( ( *hHrtf )->ModelEval.hrfModR ); - -#ifndef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES - for ( i = 0; i < 3; i++ ) - { - free( ( *hHrtf )->lr_energy_and_iac_dyn[i] ); - } -#endif } ivas_HRTF_binary_close( hHrtf ); @@ -1982,7 +1850,6 @@ void destroy_parambin_hrtf( return; } -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES /*---------------------------------------------------------------------* * destroy_hrtf_statistics() * @@ -2002,4 +1869,3 @@ ivas_error destroy_hrtf_statistics( ivas_HRTF_statistics_close( hHrtfStatistics ); return IVAS_ERR_OK; } -#endif diff --git a/lib_util/hrtf_file_reader.h b/lib_util/hrtf_file_reader.h index 0048def686b7e6bbba6ca375332ac219aeb4f29e..ab3254806f681abf6f0cf1dd8fc23644b4630ef1 100644 --- a/lib_util/hrtf_file_reader.h +++ b/lib_util/hrtf_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -98,13 +98,9 @@ ivas_error load_HRTF_binary( *---------------------------------------------------------------------*/ ivas_error load_reverb_binary( -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics, /* i/o: HRTF statistics handle */ int32_t sampleRate, /* i : sample rate */ -#else - IVAS_DEC_HRTF_HANDLE hHrtf, /* i/o: HRTF handle */ -#endif - const hrtfFileReader *hrtfReader /* i/o: pointer to hrtfFileReader handle */ + const hrtfFileReader *hrtfReader /* i/o: pointer to hrtfFileReader handle */ ); /*---------------------------------------------------------------------* * create_SetOfHRTF_from_binary() @@ -182,7 +178,6 @@ void destroy_td_hrtf( IVAS_DEC_HRTF_HANDLE *hHRTF /* i/o: HRTF handle */ ); -#ifdef NONBE_FIX_922_PRECOMPUTED_HRTF_PROPERTIES /*---------------------------------------------------------------------* * destroy_hrtf_statistics() * @@ -192,6 +187,5 @@ void destroy_td_hrtf( ivas_error destroy_hrtf_statistics( IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics /* i/o: HRTF statistics handle */ ); -#endif #endif /* IVAS_HRTF_FILE_READER_H */ diff --git a/lib_util/ism_file_reader.c b/lib_util/ism_file_reader.c index b298b25bc88def43051bcff8f7394fcd6e18889c..48e870ac356c5b749ec78ad6237ddd7d4a79be1d 100644 --- a/lib_util/ism_file_reader.c +++ b/lib_util/ism_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/ism_file_reader.h b/lib_util/ism_file_reader.h index 8ddb67704e4db1c30bddb2e3dd207a226b6de90e..886ebb34be8b57a4e5b869e2cd75ceb7573918ca 100644 --- a/lib_util/ism_file_reader.h +++ b/lib_util/ism_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/ism_file_writer.c b/lib_util/ism_file_writer.c index ca845323e72b69afa5c0cd9c1bb1b7228c136676..ac838bb4f5eceb46e5c945eb4366ae294636d1f4 100644 --- a/lib_util/ism_file_writer.c +++ b/lib_util/ism_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/ism_file_writer.h b/lib_util/ism_file_writer.h index d9f731e87e56b8f0b333d725d813047320d82a39..b4faa45988e08abdcfc68638e1e35cfad0bb2ab8 100644 --- a/lib_util/ism_file_writer.h +++ b/lib_util/ism_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/jbm_file_reader.c b/lib_util/jbm_file_reader.c index 1be5c223658691c85b01d403c1ea79f330e82658..01ca956f75a8527b62b560b9e183f1f07b1ff51f 100644 --- a/lib_util/jbm_file_reader.c +++ b/lib_util/jbm_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/jbm_file_reader.h b/lib_util/jbm_file_reader.h index 64d2d17e45efdf246ab05ec56de690c5fd252b70..379506ee6a63b86a440b55d861a3cb981a5ff899 100644 --- a/lib_util/jbm_file_reader.h +++ b/lib_util/jbm_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/jbm_file_writer.c b/lib_util/jbm_file_writer.c index 584a22bc7f97df3c3084e1a4045356f6547e80bf..6e26fe7035d2bfb21de508f8906040049a5556b6 100644 --- a/lib_util/jbm_file_writer.c +++ b/lib_util/jbm_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/jbm_file_writer.h b/lib_util/jbm_file_writer.h index c82c38e0f9bcbfd9b039a5c31a4b863900e21139..fad5ec81e8bd2d0cb0d4cf5ffae8052760d3ebf9 100644 --- a/lib_util/jbm_file_writer.h +++ b/lib_util/jbm_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 9b39fab486bd99ab3259fc5dd6770351792e1e6e..90b734d07a083d6026b7385377111c27dddba664 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/ls_custom_file_reader.h b/lib_util/ls_custom_file_reader.h index df7fe6bde7a929cb7dff5ae4a4e17d34ab0b58eb..b5def337621e2465952aa70d087c236cc0835b82 100644 --- a/lib_util/ls_custom_file_reader.h +++ b/lib_util/ls_custom_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 5fda0fcc3c146b9fa9c99b467b2983e348c99675..f59f514d7fcf884f0a0160e60699d8c345e61d40 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/masa_file_reader.h b/lib_util/masa_file_reader.h index 5f3f2fec2a9ce19d539ddad48bc29ba53e3c7b0d..de55035c7b072740dbd3678921e5eaaf5899d0c7 100644 --- a/lib_util/masa_file_reader.h +++ b/lib_util/masa_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/masa_file_writer.c b/lib_util/masa_file_writer.c index 171eb4a2e6b88b89def390e944f8321048a3c3b8..73ce19d593c0a4409392798bb23a27789b22b7e5 100644 --- a/lib_util/masa_file_writer.c +++ b/lib_util/masa_file_writer.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -41,12 +41,12 @@ typedef struct masaMetaDelayStorage { MASA_DECRIPTIVE_META descriptiveMeta; - uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; - uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; - uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; - uint8_t surroundCoherence[DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; - uint8_t diffuseToTotalRatio[DELAY_MASA_PARAM_DEC_SFR][MASA_FREQUENCY_BANDS]; - + uint16_t directionIndex[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR + 1][MASA_FREQUENCY_BANDS]; + uint8_t directToTotalRatio[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR + 1][MASA_FREQUENCY_BANDS]; + uint8_t spreadCoherence[MASA_MAXIMUM_DIRECTIONS][DELAY_MASA_PARAM_DEC_SFR + 1][MASA_FREQUENCY_BANDS]; + uint8_t surroundCoherence[DELAY_MASA_PARAM_DEC_SFR + 1][MASA_FREQUENCY_BANDS]; + uint8_t diffuseToTotalRatio[DELAY_MASA_PARAM_DEC_SFR + 1][MASA_FREQUENCY_BANDS]; + uint8_t prevDelay; } MASA_META_DELAY_STORAGE; struct MasaFileWriter @@ -88,50 +88,86 @@ static void getExtMasaMetadataFileName( static void delayMasaMetadata( MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: New input metadata which is inplace replaced with delayed metadata frame */ - MASA_META_DELAY_STORAGE *delayStorage /* i/o: Storage for 10 ms of metadata and related descriptive metadata */ -) + MASA_META_DELAY_STORAGE *delayStorage, /* i/o: Storage for 15 ms of metadata and related descriptive metadata */ + uint8_t delayNsf ) { int16_t dir, sf, band; uint8_t currentNumberOfDirections; + int16_t storeReadOffset; /* Move meta to delay and output. Always use two directions as the metadata is prepared to contain zero energy second direction * if there is 1dir meta. */ - for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES - DELAY_MASA_PARAM_DEC_SFR; sf++ ) + /* stable state expected results delay change expected results + delayNsf = 2 delayNsf = 3 delayNsf = 3 (from 2) delayNsf = 2 (from 3) + ext[0] = delayStorage[0] (prev ext[2]) ext[0] = delayStorage[0] (prev ext[1]) ext[0] = delayStorage[0] (prev ext[2]) ext[0] = delayStorage[1] (prev ext[2]) + ext[1] = delayStorage[1] (prev ext[3]) ext[1] = delayStorage[1] (prev ext[2]) ext[1] = delayStorage[1] (prev ext[3]) ext[1] = delayStorage[2] (prev ext[3]) + ext[2] = ext[0] ext[2] = delayStorage[2] (prev ext[3]) ext[2] = delayStorage[1] (prev ext[3]) ext[2] = ext[0] + ext[3] = ext[1] ext[3] = ext[0] ext[3] = ext[0] ext[3] = ext[0] + delayStorage[0] = ext[2] delayStorage[0] = ext[1] delayStorage[0] = ext[1] delayStorage[0] = ext[2] + delayStorage[1] = ext[3] delayStorage[1] = ext[2] delayStorage[1] = ext[2] delayStorage[1] = ext[3] + delayStorage[2] = ext[3] delayStorage[2] = ext[3] + */ + storeReadOffset = delayStorage->prevDelay > delayNsf ? delayStorage->prevDelay - delayNsf : 0; /* delay decreases: read later from storage -> discard one sf */ + + for ( sf = 0; sf < delayNsf; sf++ ) { for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) { uint16_t temp_u16; uint8_t temp_u8; + int16_t toStoreIdx, reOrgIdx, storeReadIdx; + + toStoreIdx = sf + MAX_PARAM_SPATIAL_SUBFRAMES - delayNsf; + reOrgIdx = sf + delayNsf; + /* when switching to longer delay, repeat the last valid sf to fill the gap */ + storeReadIdx = ( ( sf + storeReadOffset ) < delayStorage->prevDelay ) ? sf + storeReadOffset : delayStorage->prevDelay - 1; + for ( dir = 0; dir < MASA_MAXIMUM_DIRECTIONS; dir++ ) { - temp_u16 = delayStorage->directionIndex[dir][sf][band]; - delayStorage->directionIndex[dir][sf][band] = extOutMeta->directionIndex[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band]; - extOutMeta->directionIndex[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->directionIndex[dir][sf][band]; + temp_u16 = delayStorage->directionIndex[dir][storeReadIdx][band]; + delayStorage->directionIndex[dir][sf][band] = extOutMeta->directionIndex[dir][toStoreIdx][band]; + if ( reOrgIdx < MAX_PARAM_SPATIAL_SUBFRAMES ) + { + extOutMeta->directionIndex[dir][reOrgIdx][band] = extOutMeta->directionIndex[dir][sf][band]; + } extOutMeta->directionIndex[dir][sf][band] = temp_u16; - temp_u8 = delayStorage->directToTotalRatio[dir][sf][band]; - delayStorage->directToTotalRatio[dir][sf][band] = extOutMeta->directToTotalRatio[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band]; - extOutMeta->directToTotalRatio[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->directToTotalRatio[dir][sf][band]; + temp_u8 = delayStorage->directToTotalRatio[dir][storeReadIdx][band]; + delayStorage->directToTotalRatio[dir][sf][band] = extOutMeta->directToTotalRatio[dir][toStoreIdx][band]; + if ( reOrgIdx < MAX_PARAM_SPATIAL_SUBFRAMES ) + { + extOutMeta->directToTotalRatio[dir][reOrgIdx][band] = extOutMeta->directToTotalRatio[dir][sf][band]; + } extOutMeta->directToTotalRatio[dir][sf][band] = temp_u8; - temp_u8 = delayStorage->spreadCoherence[dir][sf][band]; - delayStorage->spreadCoherence[dir][sf][band] = extOutMeta->spreadCoherence[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band]; - extOutMeta->spreadCoherence[dir][sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->spreadCoherence[dir][sf][band]; + temp_u8 = delayStorage->spreadCoherence[dir][storeReadIdx][band]; + delayStorage->spreadCoherence[dir][sf][band] = extOutMeta->spreadCoherence[dir][toStoreIdx][band]; + if ( reOrgIdx < MAX_PARAM_SPATIAL_SUBFRAMES ) + { + extOutMeta->spreadCoherence[dir][reOrgIdx][band] = extOutMeta->spreadCoherence[dir][sf][band]; + } extOutMeta->spreadCoherence[dir][sf][band] = temp_u8; } - temp_u8 = delayStorage->surroundCoherence[sf][band]; - delayStorage->surroundCoherence[sf][band] = extOutMeta->surroundCoherence[sf + DELAY_MASA_PARAM_DEC_SFR][band]; - extOutMeta->surroundCoherence[sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->surroundCoherence[sf][band]; + temp_u8 = delayStorage->surroundCoherence[storeReadIdx][band]; + delayStorage->surroundCoherence[sf][band] = extOutMeta->surroundCoherence[toStoreIdx][band]; + if ( reOrgIdx < MAX_PARAM_SPATIAL_SUBFRAMES ) + { + extOutMeta->surroundCoherence[reOrgIdx][band] = extOutMeta->surroundCoherence[sf][band]; + } extOutMeta->surroundCoherence[sf][band] = temp_u8; - temp_u8 = delayStorage->diffuseToTotalRatio[sf][band]; - delayStorage->diffuseToTotalRatio[sf][band] = extOutMeta->diffuseToTotalRatio[sf + DELAY_MASA_PARAM_DEC_SFR][band]; - extOutMeta->diffuseToTotalRatio[sf + DELAY_MASA_PARAM_DEC_SFR][band] = extOutMeta->diffuseToTotalRatio[sf][band]; + temp_u8 = delayStorage->diffuseToTotalRatio[storeReadIdx][band]; + delayStorage->diffuseToTotalRatio[sf][band] = extOutMeta->diffuseToTotalRatio[toStoreIdx][band]; + if ( reOrgIdx < MAX_PARAM_SPATIAL_SUBFRAMES ) + { + extOutMeta->diffuseToTotalRatio[reOrgIdx][band] = extOutMeta->diffuseToTotalRatio[sf][band]; + } extOutMeta->diffuseToTotalRatio[sf][band] = temp_u8; } } + /* Finalize descriptive meta by using new frame except for number of directions which is the larger of the two */ currentNumberOfDirections = extOutMeta->descriptiveMeta.numberOfDirections; if ( delayStorage->descriptiveMeta.numberOfDirections > extOutMeta->descriptiveMeta.numberOfDirections ) @@ -140,6 +176,8 @@ static void delayMasaMetadata( } delayStorage->descriptiveMeta.numberOfDirections = currentNumberOfDirections; + delayStorage->prevDelay = delayNsf; + return; } @@ -182,6 +220,7 @@ ivas_error MasaFileWriter_open( if ( !delayCompensationEnabled ) { self->delayStorage = calloc( sizeof( MASA_META_DELAY_STORAGE ), 1 ); + self->delayStorage->prevDelay = DELAY_MASA_PARAM_DEC_SFR; } *masaWriter = self; @@ -197,8 +236,9 @@ ivas_error MasaFileWriter_open( *---------------------------------------------------------------------*/ ivas_error MasaFileWriter_writeFrame( - MasaFileWriter *self, /* i/o: MasaFileWriter handle */ - MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta /* i/o: MASA ext out meta handle to be written */ + MasaFileWriter *self, /* i/o: MasaFileWriter handle */ + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta, /* i/o: MASA ext out meta handle to be written */ + const float *decDelay /* i : decoding audio delay */ ) { if ( self == NULL ) @@ -212,10 +252,12 @@ ivas_error MasaFileWriter_writeFrame( /* If delay storage has been reserved, then we are in the normal mode for the decoder * (i.e., no delay compensation for PCM) which means that metadata should be delayed - * by two subframes (10 ms). Descriptive metadata is a combined result. */ + * by two or three subframes (10 or 15 ms). Descriptive metadata is a combined result. */ if ( self->delayStorage ) { - delayMasaMetadata( hMasaExtOutMeta, self->delayStorage ); + uint8_t delayFrames = (uint8_t) ( (int32_t) ( ( *decDelay ) * 48000 ) / L_SPATIAL_SUBFR_48k ); + + delayMasaMetadata( hMasaExtOutMeta, self->delayStorage, delayFrames ); } numDirections = hMasaExtOutMeta->descriptiveMeta.numberOfDirections + 1; diff --git a/lib_util/masa_file_writer.h b/lib_util/masa_file_writer.h index 0619ff02e75223df155abd429e9c39967227ceeb..3644881f35c84635f2692fc48befbb4707d72eb1 100644 --- a/lib_util/masa_file_writer.h +++ b/lib_util/masa_file_writer.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -34,6 +34,7 @@ #define IVAS_MASA_FILE_WRITER_H #include "common_api_types.h" +#include "options.h" #include @@ -47,8 +48,9 @@ ivas_error MasaFileWriter_open( ); ivas_error MasaFileWriter_writeFrame( - MasaFileWriter *self, /* i/o: MasaFileWriter handle */ - IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta /* i/o: MASA ext out meta handle to be written */ + MasaFileWriter *self, /* i/o: MasaFileWriter handle */ + IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta, /* i/o: MASA ext out meta handle to be written */ + const float *decDelay /* i : decoding audio delay */ ); void MasaFileWriter_close( diff --git a/lib_util/mime_io.c b/lib_util/mime_io.c index b5c257bb49558d5c59d02977a566974ff30b5fb2..74d0e4d7fbfc09d2f59c777c7b46163ee9abf54b 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/mime_io.h b/lib_util/mime_io.h index 91b9160529600b46447baf60dca5485c71a3ec1a..6ce5070c44bf5817a76a78d3ee542acad801aed7 100644 --- a/lib_util/mime_io.h +++ b/lib_util/mime_io.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index e5101cfe92a7eaa4ca970241bd7c78365d01f4ce..decafb0a46dbc19e5de42df5fd09436c54d9eaa9 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -2241,7 +2241,7 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_INVALID_RENDER_CONFIG; } idx = strtol( strtok( NULL, ":" ), NULL, 0 ); - pRenderConfigReader->pAE->id = idx; + pRenderConfigReader->pAE[acIdx].id = idx; aeHasFgIdx = aeHasPredelay = aeHasRt60 = aeHasDsr = FALSE; aeHasERsize = aeHasERabs = FALSE; @@ -2301,7 +2301,7 @@ ivas_error RenderConfigReader_read( /* RT60 */ else if ( strcmp( item, "RT60" ) == 0 ) { - if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) ) + if ( read_txt_vector( pValue, pRenderConfigReader->pAE[acIdx].pFG->nrBands, pRenderConfigReader->pAE[acIdx].pRT60 ) ) { errorHandler( item, ERROR_VALUE_INVALID ); return IVAS_ERR_INVALID_RENDER_CONFIG; @@ -2311,7 +2311,7 @@ ivas_error RenderConfigReader_read( /* DSR */ else if ( strcmp( item, "DSR" ) == 0 ) { - if ( read_txt_vector( pValue, pRenderConfigReader->pFG[idx].nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) ) + if ( read_txt_vector( pValue, pRenderConfigReader->pAE[acIdx].pFG->nrBands, pRenderConfigReader->pAE[acIdx].pDSR ) ) { errorHandler( item, ERROR_VALUE_INVALID ); return IVAS_ERR_INVALID_RENDER_CONFIG; @@ -2452,7 +2452,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif if ( strcmp( item, "CODECDELAY" ) == 0 ) { if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_delay_ms ) ) diff --git a/lib_util/render_config_reader.h b/lib_util/render_config_reader.h index 2e929643282ebc55dfdaff5c25f5c50cf0a26356..445ced79abdb905cc094a5b8d51311d4f3f8f4ba 100644 --- a/lib_util/render_config_reader.h +++ b/lib_util/render_config_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 19721f49bad23f5bf75ed460e4a82aff3f1bf40a..b52e9acf4adc320b999a18fe6099e25478c21067 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/rotation_file_reader.h b/lib_util/rotation_file_reader.h index 1ae772fceb19d61eb28392282f0494222b705ffc..3f98ea5b0c8473bb691e2dcda2143d2ac7f393c3 100644 --- a/lib_util/rotation_file_reader.h +++ b/lib_util/rotation_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/rtpdump.c b/lib_util/rtpdump.c index 262f114a13ef015d83562bb35d5d978ed0bc794a..9f8784947314990b7d0a41aae0a357510c1b7bec 100644 --- a/lib_util/rtpdump.c +++ b/lib_util/rtpdump.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/rtpdump.h b/lib_util/rtpdump.h index 46300c0e9a1e85fbd704ea54df6da123e40df741..b97ec97d839a231fa1aa98ee82016a719f1a94fa 100644 --- a/lib_util/rtpdump.h +++ b/lib_util/rtpdump.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c index 66f0a17ecee72eb9e3f7b7937f914dae8d657858..0f16e25984a5742d1519aef46bdb5e68676556ca 100644 --- a/lib_util/split_rend_bfi_file_reader.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/split_rend_bfi_file_reader.h b/lib_util/split_rend_bfi_file_reader.h index 341ef3ed657bab7c6a1f7fd9a9836c36d60106bb..f0af65254411fcd7c3b0f8f19e3abcc7f82510ea 100644 --- a/lib_util/split_rend_bfi_file_reader.h +++ b/lib_util/split_rend_bfi_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index e7cecf313388309d74a641a73a2819ed9ba0bed1..d1a85776bd61eaf1aa9cda995c4a312d98aebc1e 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index 40028c2ad88913dddc4dcba6b9aa923ed9a3f625..e933fe3df3a2f5f955a9c62f19c8c773f8efcdf5 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/tinywavein_c.h b/lib_util/tinywavein_c.h index cddcb6450184d85979aae605f9656ec962aa98a1..0fd1b7a65b47e0ee1276fd937cbd9abce4d55b25 100644 --- a/lib_util/tinywavein_c.h +++ b/lib_util/tinywavein_c.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/tinywaveout_c.h b/lib_util/tinywaveout_c.h index db60146a02ae467d7b637ecb2adaca525e065079..9b11e325a72f5bf33ad5a84763244b00c2b841df 100644 --- a/lib_util/tinywaveout_c.h +++ b/lib_util/tinywaveout_c.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/tsm_scale_file_reader.c b/lib_util/tsm_scale_file_reader.c index fbd1824d9dfd4d7219ad72c18549bc19a9d016a9..147f077f66f498c1254179ad7a79367d261c5ad1 100644 --- a/lib_util/tsm_scale_file_reader.c +++ b/lib_util/tsm_scale_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -36,6 +36,9 @@ #include #include +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + struct TsmScaleFileReader { FILE *file; @@ -146,3 +149,6 @@ const char *TsmScaleFileReader_getFilePath( return self->file_path; } + +#endif +#endif diff --git a/lib_util/tsm_scale_file_reader.h b/lib_util/tsm_scale_file_reader.h index 55ee20f8cfdb47fd178bb84f948c833c9b3de10a..7666a3b5946a1a1aeb5868dd5f2ff9e48ebd03f1 100644 --- a/lib_util/tsm_scale_file_reader.h +++ b/lib_util/tsm_scale_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -37,6 +37,9 @@ /* clang-format off */ +#ifdef DEBUGGING +#ifdef VARIABLE_SPEED_DECODING + typedef struct TsmScaleFileReader TsmScaleFileReader; @@ -59,6 +62,9 @@ const char *TsmScaleFileReader_getFilePath( TsmScaleFileReader* self /* i/o: TsmScaleFileReader handle */ ); +#endif +#endif + /* clang-format on */ #endif /* IVAS_TSM_SCALE_FILE_READER_H */ diff --git a/lib_util/vector3_pair_file_reader.c b/lib_util/vector3_pair_file_reader.c index 9e03358b91c901e9c6f2875bb8f714cce00a86db..24adde7e23c0d9ad1b7ea333f867b67b311cf18c 100644 --- a/lib_util/vector3_pair_file_reader.c +++ b/lib_util/vector3_pair_file_reader.c @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/lib_util/vector3_pair_file_reader.h b/lib_util/vector3_pair_file_reader.h index e4691939220cfaded272c9481c715f73cd018d65..3255fb315442f4f5544e88d1cf62595be837e4af 100644 --- a/lib_util/vector3_pair_file_reader.h +++ b/lib_util/vector3_pair_file_reader.h @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/readme.txt b/readme.txt index e39174163960b44daf988c902afd177883de5bc7..25275a79516b91aa8a0d3fa8131155cd441f5e68 100644 --- a/readme.txt +++ b/readme.txt @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/readme_split_rendering.txt b/readme_split_rendering.txt index dbf76e012ff467d4ff5e2a098ec7652cb4773246..60db2cc5a6f7e184af5657b33465d60469f2b474 100644 --- a/readme_split_rendering.txt +++ b/readme_split_rendering.txt @@ -1,6 +1,6 @@ /****************************************************************************************************** - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other diff --git a/scripts/IvasBuildAndRun.py b/scripts/IvasBuildAndRun.py index 554c216b184eb47331ffbad3947ad767ae16d17f..6113c2ae3e3b3148b16d6b4aaa1eaee9d29c920e 100755 --- a/scripts/IvasBuildAndRun.py +++ b/scripts/IvasBuildAndRun.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -33,9 +33,9 @@ import os.path import sys -from pyivastest.IvasSvnBuilder import * -from pyivastest import IvasScriptsCommon import pyivastest.constants as constants +from pyivastest import IvasScriptsCommon +from pyivastest.IvasSvnBuilder import * class IvasBuildAndRun(IvasScriptsCommon.IvasScript): diff --git a/scripts/IvasBuildAndRunChecks.py b/scripts/IvasBuildAndRunChecks.py index 680f7e16d09763dba43d8f1d1e18263796eeeb99..4bca48a672fd4b3febddc6c995d5b8c7d80e72dc 100755 --- a/scripts/IvasBuildAndRunChecks.py +++ b/scripts/IvasBuildAndRunChecks.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other @@ -33,10 +33,9 @@ import os.path import sys -from pyivastest.IvasSvnBuilder import * -from pyivastest import IvasScriptsCommon import pyivastest.constants as constants - +from pyivastest import IvasScriptsCommon +from pyivastest.IvasSvnBuilder import * RET_CODE_FAILURE = 101 @@ -92,7 +91,8 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): "--rebuild", help="force a rebuild of the binaries", action="store_true" ) self.parser.add_argument( - "--usan_supp_file", help="suppression file for undef behaviour sanitizer", + "--usan_supp_file", + help="suppression file for undef behaviour sanitizer", default=None, ) @@ -184,7 +184,9 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): checks_ret_val.append(ret_val) if self.args["create_html_output"]: cmd = ["git", "rev-parse", "HEAD"] - commit_hash = subprocess.run(cmd, capture_output=True).stdout.decode("utf8") + commit_hash = subprocess.run(cmd, capture_output=True).stdout.decode( + "utf8" + ) br.build_and_run_dict[check]["analyzer"].write_html_file( check, self.args["create_html_output"], commit_hash ) @@ -211,10 +213,11 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): failed_encs = runner.failed_modes["enc"] failed_decs = runner.failed_modes["dec"] if len(failed_encs) > 0 or len(failed_decs) > 0 or ret_val != 0: - returncode = RET_CODE_FAILURE + returncode = RET_CODE_FAILURE return returncode + if __name__ == "__main__": script = IvasBuildAndRunChecks() sys.exit(script.run()) diff --git a/scripts/README.md b/scripts/README.md index bc7ae8f32e89b4d451703522a85c3d1494218f82..880e4bf6add10372c6579a307cf333cccc92755b 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,6 +1,6 @@